I would like to query a relational database if a set of items exists.
The data I am modeling are of the following form:
key1 = [ item1, item3, item5
aleksis solution requires an specific query for every posssible item set. the following suggestion provides a generic solution in the sense that the item set to be queried can be factored in as a result set of another query - just replace the set containment operators by a suitable subquery.
SELECT CASE COUNT(ffffd.key) WHEN 0 THEN NULL ELSE MIN(ffffd.key) END
FROM (
SELECT s4.key
, COUNT(*) icount
FROM sets s4
JOIN (
SELECT DISTINCT d.key
FROM (
SELECT s1.key
FROM sets s1
WHERE s1.item IN ('item1', 'item3', 'item5')
MINUS
SELECT s2.key
FROM sets s2
WHERE s2.item NOT IN ('item1', 'item3', 'item5')
) d
) dd ON ( dd.key = s4.key )
GROUP BY s4.key
) ffffd
WHERE ffffd.icount = (
SELECT COUNT(*)
FROM (
SELECT DISTINCT s3.item
FROM sets s3
WHERE s3.item IN ('item1', 'item3', 'item5')
)
)
;
the result set dd delivers a candidate set of keys who do not asscociate with other items than those from the set to be tested. the only ambiguity may arise from keys who reference a proper subset of the tested item set. thus we count the number of items associated with the keys of dd and choose that key where this number matches the cardinality of the tested item set. if such a key exists it is unique (as we know that the item sets are unique). the case expression in the outermost select is just a fancy way to guarantee that their will be no empty result set, i.e. a null value will be returned if the item set is not represented by the relation.
maybe this solution will be useful to you,
best regards
carsten