我想比较表-1的columnn-A和Table-2的B列。两者都有逗号分隔值。
在我的情况下,如果列B中的所有值都存在于列A中,我必须返回TRUE
错误。请指教。例如:
1.Column A有a,b,c,def列B有a,c,b它应该返回TRUE
2.第1列有vvv,ccc,rr第2列有ccc,rr,125它应该返回FALSE
3.第1列为空,第2列为空,应返回TRUE
请帮忙
答案 0 :(得分:1)
可以通过以下SQL完成:
with t1 as( select '1111,1985,433435,5765' as colA from dual union all
select '232323,7777,8888,9999' as colA from dual union all
select '111,2000,433435,5765' as colA from dual),
t2 as ( select '1111,466576,24323' as colB from dual union all
select '11111,1985,435657' as colb from dual union all
select '2222,232323,24989323' as colb from dual )
select colA from t1 where exists(
select 1 from t2 where REGEXP_COUNT(','||t1.colA||',' , ',('||REPLACE(t2.colB, ',' , '|') || '),' ) > 0)
答案 1 :(得分:0)
希望这段代码有所帮助。
SELECT DECODE(NULLIF(
(SELECT LISTAGG(x.col_val,',') WITHIN GROUP(
ORDER BY x.col_val)intrsctnVal
FROM
(SELECT SUBSTR(REPLACE(COL2,',',''),LEVEL,1) col_val
FROM
(SELECT 'a,b,c' AS COL2 FROM DUAL
)B
CONNECT BY level <= regexp_count(col2,',')+1
INTERSECT
SELECT SUBSTR(REPLACE(COL1,',',''),LEVEL,1) col_val
FROM
(SELECT 'a,b,c,d' AS COL1 FROM DUAL
)A
CONNECT BY LEVEL <= REGEXP_COUNT(COL1,',')+1
)X
),
(SELECT 'a,b,c' AS COL2 FROM DUAL
)),NULL,'TRUE','FALSE') MATCH
FROM DUAL;
答案 2 :(得分:0)
最终,我得到了它) 对我来说,仅使用SQL解决它是一项有趣的任务:
private String key;
public void generateFile() {
key = kickoffFileGeneration(); // spawns worker thread, creates file in FileCache
}
public void checkForDownloadReady() {
STATUS status = FileCache.getFileStatus(key);
if (status == STATUS.READY) {
FileCache.setFileStatus(key, STATUS.HANDLED);
RequestContext.getCurrentInstance().execute("doTheActualDownload()");
} else if (status == STATUS.FAILED) {
logger.error("Failure creating file. Wait loop will end.");
} else if (status == STATUS.OPEN || status == STATUS.NEW){
RequestContext.getCurrentInstance().execute("downloadFileWhenReady()");
}
}
1步:联合两个表:
B N SORTED BOOL
---------- ---------- -------------------------------------------------------------------------------- -----
1 1 [a],[b],[c] true
1 2 [ccc],[rr],[vvv] false
1 3 [] true
2步:计算分隔符:
SQL> with
2 t1 as (
3 select 1 n, 'c,b,a' c from dual
4 union all
5 select 2 n, 'vvv,ccc,rr' c from dual
6 union all
7 select 3 n, null c from dual),
8 t2 as (
9 select 1 n, 'a,b,c' c from dual
10 union all
11 select 2 n, 'ccc,rr,125' c from dual
12 union all
13 select 3 n, null c from dual),
14 t12 as (select 1 b, n, c from t1 union all select 2 b, n, c from t2)
15 select * from t12
16 /
B N C
---------- ---------- ----------
1 1 c,b,a
1 2 vvv,ccc,rr
1 3
2 1 a,b,c
2 2 ccc,rr,125
2 3
6 rows selected
3步:计算边界值
SQL> with
2 t1 as (
3 select 1 n, 'c,b,a' c from dual
4 union all
5 select 2 n, 'vvv,ccc,rr' c from dual
6 union all
7 select 3 n, null c from dual),
8 t2 as (
9 select 1 n, 'a,b,c' c from dual
10 union all
11 select 2 n, 'ccc,rr,125' c from dual
12 union all
13 select 3 n, null c from dual),
14 t12 as (select 1 b, n, c from t1 union all select 2 b, n, c from t2),
15 t as (select b, n, c, nvl(length(regexp_replace(c, '[^,]+')) + 1, 1) cnt from t12)
16 select * from t
17 /
B N C CNT
---------- ---------- ---------- ----------
1 1 c,b,a 3
1 2 vvv,ccc,rr 3
1 3 1
2 1 a,b,c 3
2 2 ccc,rr,125 3
2 3 1
6 rows selected
4步:为行生成新查询
SQL> with
2 t1 as (
3 select 1 n, 'c,b,a' c from dual
4 union all
5 select 2 n, 'vvv,ccc,rr' c from dual
6 union all
7 select 3 n, null c from dual),
8 t2 as (
9 select 1 n, 'a,b,c' c from dual
10 union all
11 select 2 n, 'ccc,rr,125' c from dual
12 union all
13 select 3 n, null c from dual),
14 t12 as (select 1 b, n, c from t1 union all select 2 b, n, c from t2),
15 t as (select b, n, c, nvl(length(regexp_replace(c, '[^,]+')) + 1, 1) cnt from t12),
16 tbrd as (select b, n, c, cnt, sum(cnt) over (order by b,n) brd from t)
17 select * from tbrd
18 /
B N C CNT BRD
---------- ---------- ---------- ---------- ----------
1 1 c,b,a 3 3
1 2 vvv,ccc,rr 3 6
1 3 1 7
2 1 a,b,c 3 10
2 2 ccc,rr,125 3 13
2 3 1 14
6 rows selected
5步:主查询
SQL> with
2 t1 as (
3 select 1 n, 'c,b,a' c from dual
4 union all
5 select 2 n, 'vvv,ccc,rr' c from dual
6 union all
7 select 3 n, null c from dual),
8 t2 as (
9 select 1 n, 'a,b,c' c from dual
10 union all
11 select 2 n, 'ccc,rr,125' c from dual
12 union all
13 select 3 n, null c from dual),
14 t12 as (select 1 b, n, c from t1 union all select 2 b, n, c from t2),
15 t as (select b, n, c, nvl(length(regexp_replace(c, '[^,]+')) + 1, 1) cnt from t12),
16 tbrd as (select b, n, c, cnt, sum(cnt) over (order by b,n) brd from t),
17 allrec as (select level lv from dual connect by level <= (select sum(cnt) from t))
18 select * from allrec
19 /
LV
----------
1
2
3
4
5
6
7
8
9
10
11
12
13
14
14 rows selected
6步:排序值
SQL> with
2 t1 as (
3 select 1 n, 'c,b,a' c from dual
4 union all
5 select 2 n, 'vvv,ccc,rr' c from dual
6 union all
7 select 3 n, null c from dual),
8 t2 as (
9 select 1 n, 'a,b,c' c from dual
10 union all
11 select 2 n, 'ccc,rr,125' c from dual
12 union all
13 select 3 n, null c from dual),
14 t12 as (select 1 b, n, c from t1 union all select 2 b, n, c from t2),
15 t as (select b, n, c, nvl(length(regexp_replace(c, '[^,]+')) + 1, 1) cnt from t12),
16 tbrd as (select b, n, c, cnt, sum(cnt) over (order by b,n) brd from t),
17 allrec as (select level lv from dual connect by level <= (select sum(cnt) from t)),
18 step5 as (select r.b, r.n, r.c, regexp_substr(c, '[^,]+', 1, r.brd - a.lv + 1) s from tbrd r, allrec a
19 where r.brd - a.lv between 0 and r.cnt - 1)
20 select * from step5
21 /
B N C S
---------- ---------- ---------- ----------
1 1 c,b,a a
1 1 c,b,a b
1 1 c,b,a c
1 2 vvv,ccc,rr rr
1 2 vvv,ccc,rr ccc
1 2 vvv,ccc,rr vvv
1 3
2 1 a,b,c c
2 1 a,b,c b
2 1 a,b,c a
2 2 ccc,rr,125 125
2 2 ccc,rr,125 rr
2 2 ccc,rr,125 ccc
2 3
14 rows selected
7步:结果
SQL> with
2 t1 as (
3 select 1 n, 'c,b,a' c from dual
4 union all
5 select 2 n, 'vvv,ccc,rr' c from dual
6 union all
7 select 3 n, null c from dual),
8 t2 as (
9 select 1 n, 'a,b,c' c from dual
10 union all
11 select 2 n, 'ccc,rr,125' c from dual
12 union all
13 select 3 n, null c from dual),
14 t12 as (select 1 b, n, c from t1 union all select 2 b, n, c from t2),
15 t as (select b, n, c, nvl(length(regexp_replace(c, '[^,]+')) + 1, 1) cnt from t12),
16 tbrd as (select b, n, c, cnt, sum(cnt) over (order by b,n) brd from t),
17 allrec as (select level lv from dual connect by level <= (select sum(cnt) from t)),
18 step5 as (select r.b, r.n, r.c, regexp_substr(c, '[^,]+', 1, r.brd - a.lv + 1) s from tbrd r, allrec a
19 where r.brd - a.lv between 0 and r.cnt - 1),
20 step6 as (
21 select b, n, listagg('[' || s || ']', ',') within group (order by s) sorted
22 from step5
23 group by b, n)
24 select * from step6
25 /
B N SORTED
---------- ---------- --------------------------------------------------------------------------------
1 1 [a],[b],[c]
1 2 [ccc],[rr],[vvv]
1 3 []
2 1 [a],[b],[c]
2 2 [125],[ccc],[rr]
2 3 []
6 rows selected
当然,使用函数要好得多,但是,我只是想找到一种只使用SQL的方法。
(2017-06-05:已添加功能)
功能可以是:
SQL> with
2 t1 as (
3 select 1 n, 'c,b,a' c from dual
4 union all
5 select 2 n, 'vvv,ccc,rr' c from dual
6 union all
7 select 3 n, null c from dual),
8 t2 as (
9 select 1 n, 'a,b,c' c from dual
10 union all
11 select 2 n, 'ccc,rr,125' c from dual
12 union all
13 select 3 n, null c from dual),
14 t12 as (select 1 b, n, c from t1 union all select 2 b, n, c from t2),
15 t as (select b, n, c, nvl(length(regexp_replace(c, '[^,]+')) + 1, 1) cnt from t12),
16 tbrd as (select b, n, c, cnt, sum(cnt) over (order by b,n) brd from t),
17 allrec as (select level lv from dual connect by level <= (select sum(cnt) from t)),
18 step5 as (select r.b, r.n, r.c, regexp_substr(c, '[^,]+', 1, r.brd - a.lv + 1) s from tbrd r, allrec a
19 where r.brd - a.lv between 0 and r.cnt - 1),
20 step6 as (
21 select b, n, listagg('[' || s || ']', ',') within group (order by s) sorted
22 from step5
23 group by b, n)
24 select t.*, decode(
25 (select 1 from step6 z
26 where z.b = 2 and z.sorted = t.sorted and rownum < 2), 1, 'true', 'false') bool
27 from step6 t where b = 1
28 /
B N SORTED BOOL
---------- ---------- -------------------------------------------------------------------------------- -----
1 1 [a],[b],[c] true
1 2 [ccc],[rr],[vvv] false
1 3 [] true
测试:
create or replace function comparesepval(vArg1 in varchar2, vArg2 in varchar2) return number result_cache deterministic
as
type tpStore is table of number index by varchar2(32);
tStore1 tpStore;
tStore2 tpStore;
nCnt number;
vVal varchar2(32);
begin
if (vArg1 is null and vArg2 is null) or (vArg1 = vArg2) then
return 1;
end if;
if vArg1 is null then
return 0;
end if;
nCnt := nvl(length(regexp_replace(vArg1, '[^,]+')), 0) + 1;
if nCnt = 1 or nCnt <> nvl(length(regexp_replace(vArg2, '[^,]+')), 0) + 1 then -- vArg1 <> vArg2
return 0;
end if;
-- parse string
for i in 1..nCnt
loop
declare
procedure prcAgr(vArg in varchar2, tStore in out tpStore)
as
vVal varchar2(32) := nvl(regexp_substr(vArg, '(.*?)(,|$)', 1, i, null, 1), ','); -- ',' - for null
begin
tStore(vVal) := case when tStore.exists(vVal) then tStore(vVal) + 1 else 1 end;
end;
begin
prcAgr(vArg1, tStore1);
prcAgr(vArg2, tStore2);
end;
end loop;
if tStore1.count <> tStore2.count then
return 0;
end if;
vVal := tStore1.first;
loop
exit when vVal is null;
if not tStore2.exists(vVal) then
return 0;
end if;
if tStore2(vVal) <> tStore1(vVal) then
return 0;
end if;
vVal := tStore1.next(vVal);
end loop;
return 1;
end;
/