如何检查值是否必须存在于另一个 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;