如何从第一个表(table_A(中提取记录,该表具有嵌入CODE值的Attr列,这些值与第二个表(
table_B:CODE&DESCRcols(相比,至少包含一个不常见的值。)从而得到table_C作为结果?这就是我目前所拥有的:
Select * From Table_A
Where Attr like '%CODE%' AND
not exist (select * from Table_B
where Table_A.Attr LIKE '%'||Table_B.CODE||'%')
表A
ID | Attr |
---|---|
1 | 代码=A111 |
2 | 代码='A111、B222、C333、D444' |
3 | 代码="D444"、"E555"、"F666"> |
4 | 代码='G777','B222' |
5 | 项目="AFRD",代码="C333"> |
6 | 项目=BYNM |
只要代码总是跟在项目后面,就可以用提取代码列表
regexp_substr(attr, '.*(CODE = ?)(.*?)', 1, 1, null, 2
并使用删除空格和引号
translate(regexp_substr(attr, '.*(CODE = ?)(.*?)', 1, 1, null, 2), q'^x' ^', 'x')
获得一个简单的逗号分隔的值列表,如G777,B222
;然后将拆分为各个元素,例如使用递归子查询因子分解;并找到其他表中不存在的。
这很混乱,但是:
with cte (id, attr, codes) as (
select id, attr,
translate(
regexp_substr(attr, '.*(CODE = ?)(.*?)', 1, 1, null, 2),
q'^x' ^', 'x'
)
from table_a
),
rcte (id, attr, codes, pos, code) as (
select id, attr, codes, 1, regexp_substr(codes, '(.*?)(,|$)', 1, 1, null, 1)
from cte
where codes is not null
union all
select id, attr, codes, pos + 1, regexp_substr(codes, '(.*?)(,|$)', 1, pos + 1, null, 1)
from rcte
where regexp_substr(codes, '(.*?)(,|$)', 1, pos + 1, null, 1) is not null
)
select distinct r.id, r.attr
from rcte r
where not exists (
select null
from table_b b
where b.code = r.code
)
给出
ATTR您必须给Table_A
一个别名,以便在嵌套的select中引用它:
SELECT *
FROM
Table_A A
WHERE
Attr LIKE '%CODE%' AND
NOT EXISTS
(
SELECT *
FROM Table_B
WHERE A.Attr LIKE '%'||Table_B.CODE||'%'
)
此外,关键字是EXISTS
而不是EXIST
。
SQL不能解析像ITEM = 'AFRD' AND CODE = 'C333'
这样的复杂的任意表达式,也不能区分C333
是代码和AFRD
是项。但是,如果项目ID总是与代码不同,这就不是问题。
请参阅:http://sqlfiddle.com/#!4/995f23/1/0
您可以在Table_A和Table_B之间使用外部联接,以便在使用正则表达式函数和分层查询(如(将逗号分隔的代码转换为每个单独代码新生成的行后,获得不匹配的代码
WITH a0 AS
(
SELECT id, CASE WHEN INSTR(attr, 'CODE')>0 THEN
REGEXP_REPLACE(attr,'(.*CODE =)+')
END AS codes
FROM Table_A
), a AS
(
SELECT id, TRIM(BOTH CHR(39) FROM TRIM(REGEXP_SUBSTR(codes,'[^,]+',1,level)) ) AS codes
FROM a0
WHERE codes IS NOT NULL
CONNECT BY LEVEL <= REGEXP_COUNT(codes, ',') + 1
AND PRIOR SYS_GUID() IS NOT NULL
AND PRIOR id = id
)
SELECT a.*
FROM Table_A a
JOIN (SELECT DISTINCT id
FROM a
LEFT JOIN Table_B
ON code = codes
WHERE code IS NULL) b
ON a.id = b.id
演示