Я предполагаю, что естественным ключом этой таблицы является document_id + subject_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 удален, поскольку он не участвует в группировке. Сделав еще один шаг вперед, я собираюсь добавить воображаемую таблицу под названием subject_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)
Очевидно, что subject_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))
Или что угодно.