我假设这个表的自然键是document_id + subject_id,而那个id是代理项;IOW、document_id 和 subject_id 是唯一的。因此,我只是假装它不存在并且唯一的约束在自然键上。
让我们从显而易见的开始。
SELECT document_id, subject_id
FROM document_subjects
WHERE subject_id IN (17,76)
这会让你得到你想要的一切以及你不想要的东西。所以我们需要做的就是过滤掉其他的东西。“其他东西”是计数不等于所需主题计数的行组。
SELECT document_id
FROM document_subjects
WHERE subject_id IN (17,76)
GROUP BY document_id
HAVING COUNT(*) = 2
请注意,subject_id 已被删除,因为它不参与分组。更进一步,我将添加一个名为subjects_i_want 的假想表,其中包含您想要的N 行主题。
SELECT document_id
FROM document_subjects
WHERE subject_id IN (SELECT subject_id FROM subjects_i_want)
GROUP BY document_id
HAVING COUNT(*) = (SELECT COUNT(*) FROM subjects_i_want)
显然,subjects_i_want 可以换成另一个子查询、临时表或其他任何东西。但是,一旦有了这个 document_id 列表,就可以在更大查询的子选择中使用它。
SELECT document_id, subject_id, ...
FROM document_subjects
WHERE document_id IN(
SELECT document_id
FROM document_subjects
WHERE subject_id IN (SELECT subject_id FROM subjects_i_want)
GROUP BY document_id
HAVING COUNT(*) = (SELECT COUNT(*) FROM subjects_i_want))
管他呢。