Как express этот SQL запрос без подзапросов - PullRequest
0 голосов
/ 26 апреля 2020

У меня есть база данных, которая содержит project, keyphrase, article, and category таблиц. Проекты могут иметь несколько ключевых фраз и несколько категорий, как и статьи. Поэтому у меня есть соответствующие таблицы соединений для каждого отношения.

У меня есть запрос, который находит все статьи, в которых есть и ключевая фраза, и категория с указанным c проектом (т.е. 26).

SELECT DISTINCT article.id, article.summary
FROM article, articles_categories, articles_keyphrases 
WHERE id = articles_categories.article_id AND id = articles_keyphrases.article_id 
AND category_id IN (SELECT category_id FROM projects_categories WHERE project_id = 26)
AND keyphrase_id IN (SELECT keyphrase_id FROM projects_keyphrases WHERE project_id = 26)

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

Ответы [ 3 ]

3 голосов
/ 26 апреля 2020

Вы можете JOIN всех четырех таблиц, чтобы получить тот же результат. Обратите внимание, что объединения через запятую заменяются десятилетиями, вместо этого следует писать объединения ANSI:

SELECT DISTINCT id, summary
FROM article a
JOIN articles_categories ac ON ac.article_id = a.id
JOIN articles_keyphrases ak ON ak.article_id = a.id
JOIN projects_categories pc ON pc.category_id = ac.category_id AND pc.project_id = 26
JOIN projects_keyphrases pk ON pk.keyphrase_id = ak.keyphrase_id AND pk.project_id = 26
2 голосов
/ 26 апреля 2020

DISTINCT не требуется (и всегда красный флаг, ИМХО).

Поскольку выбраны только поля из таблицы a, вы можете избежать создания дубликатов (и необходимости их подавлять). позже), сжимая все ненужные ссылки на таблицы в подзапросы exist () -:


SELECT id, summary
FROM article a
WHERE EXISTS (
        SELECT * FROM articles_categories ac 
        JOIN projects_categories pc
            ON pc.category_id = ac.category_id AND pc.project_id = 26
        WHERE ac.article_id = a.id
        )
AND EXISTS      (
        SELECT * FROM articles_keyphrases ak 
        JOIN projects_keyphrases pk
            ON pk.keyphrase_id = ak.keyphrase_id AND pk.project_id = 26
        WHERE ak.article_id = a.id
        )
        ;
1 голос
/ 26 апреля 2020

Поскольку @Nick уже опубликовал отличный ответ, я поделюсь тем, что не отвечает на ваш вопрос, но наиболее эффективно:

select distinct a.id, a.summary
from article a
join articles_categories ac on ac.article_id = a.id
join articles_keyphrases ak on ak.article_id = a.id
and exists (select * from projects_categories pc where pc.category_id = ac.category_id and pc.project_id = 26)
and exists (select * from projects_keyphrases pk where pk.keyphrase_id = ak.keyphrase_id and pk.project_id = 26)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...