Relational division:
CREATE TABLE ztable
( c1 integer not NULL
, c2 integer not null
, PRIMARY KEY (c1,c2)
);
INSERT INTO ztable(c1,c2) values
(1 , 1) -- [c1=1] should match
,(1 , 2)
,(1 , 3)
,(2 , 3) -- [c1=2] should NOT match
,(2 , 4)
;
WITH musthave (val) AS (VALUES (1), (2))
SELECT distinct c1
FROM ztable zt
WHERE NOT EXISTS ( -- we DONT WANT the records
SELECT * FROM musthave mh
WHERE NOT EXISTS ( -- for which one of the musthaves is missing
SELECT * FROM ztable nx
WHERE nx.c1 = zt.c1
AND nx.c2 = mh.val
)
)
;
-- For smaller problems (limited set of musthave values) you could just do:
SELECT distinct c1
FROM ztable zt
WHERE zt.c2 = 1
AND EXISTS (
SELECT *
FROM ztable t2
WHERE t2.c1 = zt.c1
AND t2.c2 = 2
);
-- and there is yet another method, which counts the matching c2 values:
SELECT DISTINCT zt.c1
FROM ztable zt
JOIN (
SELECT c1, COUNT(DISTINCT c2) AS cnt
FROM ztable t2
WHERE t2.c2 IN (1, 2)
GROUP BY c1
) zzz ON zzz.c1= zt.c1
WHERE zzz.cnt = 2
;