'How to check if value must exist in another table?
I have a scenario where reference table ref has a column with different values. I need all those values to be available in other table, can you help with a query?
ref table:
description
----------
abc
bcd
cdf
data table:
id | Description
-------------------
123| abc
123| bcd
123| cdf
124| abc
124| bcd
output should be:
123| abc
123| bcd
123| cdf
I am able to get the matching entries, but I need only those entries that matches with all values.
Solution 1:[1]
You can build a "key" to join on by combining all of the values for each ID in the DATA table and compare that to a "key" containing all of the values from the REF table.
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
Solution 2:[2]
Create a cross join between the unique IDs in the data and the list of reference values, then left join that result with the actual data. If the count of matching rows is the same as the count of rows, then that id has each of the reference values.
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;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | EJ Egyed |
| Solution 2 | FlexYourData |
