В настоящее время я работаю над системой, позволяющей помечать документы ключевыми словами и иметь таблицу вида:

CREATE TABLE `KeywordsToDocuments` (
    `keywordID` int NOT NULL,
    `documentID` int NOT NULL);

Возможно, чтобы каждый документ был связан со многими ключевыми словами, и чтобы каждое ключевое слово было связано со многими документами. К сожалению, простой оператор AND не позволяет достичь того, что мне нужно, поскольку ни одна строка не будет удовлетворять нескольким значениям KeywordID, вместо этого публикация ассоциируется с несколькими ключевыми словами путем включения ее ID в несколько строк с различными keywordID.

Я пытаюсь написать запрос, который выдаст мне список документов, помеченных всеми произвольными ключевыми словами. Моя первоначальная попытка заключалась в следующем, в котором используется оператор INTERSECT:

SELECT documentID FROM KeywordsToDocuments WHERE KeywordID=keyword1
INTERSECT
SELECT documentID FROM KeywordsToDocuments WHERE KeywordID=keyword2
...

Вместо ... может быть произвольное количество подобных утверждений для дальнейших ключевых слов. Этот запрос строится PHP-скриптом динамически.

Я пытаюсь найти все документы, которые связаны с каждым ключевым словом по отдельности, затем из этих наборов результатов найти пересечение, которое будет представлять собой документы, связанные со всеми запрошенными ключевыми словами.

Но недавно я узнал, что MySQL не поддерживает оператор INTERSECT. Я искал альтернативы, но все ресурсы, которые я нашел по замене INTERSECT, были сосредоточены на его использовании для объединения результатов из двух разных таблиц. В этом случае я не вижу способа преобразования в другой оператор, такой как INNER JOIN.

Как заставить подобный запрос работать без использования оператора INTERSECT, чтобы обеспечить совместимость с MySQL?

Vality

Ответы (1)

Я предпочитаю подходить к этим запросам, используя агрегацию и предложение having:

SELECT documentID
FROM KeywordsToDocuments
WHERE KeywordID IN (keyword1, keyword2)
GROUP BY documentID
HAVING COUNT(*) = 2;

Это стандартный SQL и должен работать в любой базе данных. Кроме того, изменяя предложение HAVING, вы можете очень гибко подходить к логике комбинаций ключевых слов, которые вы ищете.

2022 WebDevInsider