如何检查值是否必须存在于另一个 table 中?
How to check if value must exist in another table?
我有一个场景,其中引用 table ref
有一列具有不同的值。我需要所有这些值在其他 table 中可用,你能帮忙查询吗?
ref
table:
description
----------
abc
bcd
cdf
data
table:
id | Description
-------------------
123| abc
123| bcd
123| cdf
124| abc
124| bcd
输出应该是:
123| abc
123| bcd
123| cdf
我能够获得匹配的条目,但我只需要那些与所有值匹配的条目。
您可以通过组合 DATA table 中每个 ID 的所有值来构建要加入的“键”,并将其与包含 REF [=] 中所有值的“键”进行比较13=].
WITH
data (id, description)
AS
(SELECT 123, 'abc' FROM DUAL
UNION ALL
SELECT 123, 'bcd' FROM DUAL
UNION ALL
SELECT 123, 'cdf' FROM DUAL
UNION ALL
SELECT 124, 'abc' FROM DUAL
UNION ALL
SELECT 124, 'bcd' FROM DUAL),
REF (description)
AS
(SELECT 'abc' FROM DUAL
UNION ALL
SELECT 'bcd' FROM DUAL
UNION ALL
SELECT 'cdf' FROM DUAL)
SELECT id, description
FROM (SELECT id,
description,
LISTAGG (description, '|')
WITHIN GROUP (ORDER BY description)
OVER (PARTITION BY id) AS djoinkey
FROM data d)
WHERE djoinkey =
(SELECT LISTAGG (description, '|') WITHIN GROUP (ORDER BY description) AS rjoinkey FROM REF);
ID DESCRIPTION
______ ______________
123 abc
123 bcd
123 cdf
SELECT id, description
FROM data d
WHERE not exists (select d.id, description from ref
except
select id, description from data)
https://dbfiddle.uk/?rdbms=oracle_21&fiddle=5150c253f9fb625bcca4bae27832554c
在数据中的唯一 ID 和参考值列表之间创建交叉联接,然后将该结果与实际数据左联接。如果匹配的行数与行数相同,则该id具有每个参考值。
create table #ref (val nvarchar(3));
insert into #ref (val)
values
('abc'),
('bcd'),
('cdf');
create table #dat (id int, val nvarchar(3));
insert into #dat (id,val)
values
(123,'abc'),
(123,'bcd'),
(123,'cdf'),
(124,'abc'),
(124,'bcd');
SELECT #dat.id, #dat.val
FROM #dat
INNER JOIN (
SELECT ids_ref.id, COUNT(*) AS vals, SUM(CASE WHEN #dat.val IS NOT NULL THEN 1 ELSE 0 END) AS dat_vals
FROM (SELECT ids.id, #ref.val FROM (SELECT DISTINCT id FROM #dat) ids, #ref) ids_ref
LEFT JOIN #dat ON ids_ref.id = #dat.id AND ids_ref.val = #dat.val
GROUP BY ids_ref.id
) chk ON #dat.id = chk.id
WHERE chk.vals = chk.dat_vals;
drop table #ref;
drop table #dat;
我有一个场景,其中引用 table ref
有一列具有不同的值。我需要所有这些值在其他 table 中可用,你能帮忙查询吗?
ref
table:
description
----------
abc
bcd
cdf
data
table:
id | Description
-------------------
123| abc
123| bcd
123| cdf
124| abc
124| bcd
输出应该是:
123| abc
123| bcd
123| cdf
我能够获得匹配的条目,但我只需要那些与所有值匹配的条目。
您可以通过组合 DATA table 中每个 ID 的所有值来构建要加入的“键”,并将其与包含 REF [=] 中所有值的“键”进行比较13=].
WITH
data (id, description)
AS
(SELECT 123, 'abc' FROM DUAL
UNION ALL
SELECT 123, 'bcd' FROM DUAL
UNION ALL
SELECT 123, 'cdf' FROM DUAL
UNION ALL
SELECT 124, 'abc' FROM DUAL
UNION ALL
SELECT 124, 'bcd' FROM DUAL),
REF (description)
AS
(SELECT 'abc' FROM DUAL
UNION ALL
SELECT 'bcd' FROM DUAL
UNION ALL
SELECT 'cdf' FROM DUAL)
SELECT id, description
FROM (SELECT id,
description,
LISTAGG (description, '|')
WITHIN GROUP (ORDER BY description)
OVER (PARTITION BY id) AS djoinkey
FROM data d)
WHERE djoinkey =
(SELECT LISTAGG (description, '|') WITHIN GROUP (ORDER BY description) AS rjoinkey FROM REF);
ID DESCRIPTION
______ ______________
123 abc
123 bcd
123 cdf
SELECT id, description
FROM data d
WHERE not exists (select d.id, description from ref
except
select id, description from data)
https://dbfiddle.uk/?rdbms=oracle_21&fiddle=5150c253f9fb625bcca4bae27832554c
在数据中的唯一 ID 和参考值列表之间创建交叉联接,然后将该结果与实际数据左联接。如果匹配的行数与行数相同,则该id具有每个参考值。
create table #ref (val nvarchar(3));
insert into #ref (val)
values
('abc'),
('bcd'),
('cdf');
create table #dat (id int, val nvarchar(3));
insert into #dat (id,val)
values
(123,'abc'),
(123,'bcd'),
(123,'cdf'),
(124,'abc'),
(124,'bcd');
SELECT #dat.id, #dat.val
FROM #dat
INNER JOIN (
SELECT ids_ref.id, COUNT(*) AS vals, SUM(CASE WHEN #dat.val IS NOT NULL THEN 1 ELSE 0 END) AS dat_vals
FROM (SELECT ids.id, #ref.val FROM (SELECT DISTINCT id FROM #dat) ids, #ref) ids_ref
LEFT JOIN #dat ON ids_ref.id = #dat.id AND ids_ref.val = #dat.val
GROUP BY ids_ref.id
) chk ON #dat.id = chk.id
WHERE chk.vals = chk.dat_vals;
drop table #ref;
drop table #dat;