如何在没有子查询的情况下表达这个 SQL 查询

How to express this SQL query without subqueries

我有一个包含 project, keyphrase, article, and category 个表的数据库。项目可以有多个关键短语和多个类别,文章也可以。所以我为每个关系都有各自的连接表。

我有一个查询,用于查找与特定项目(即 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)

我试图找到一种不同的方式来编写它,这样就没有任何子查询了。这对我来说主要是一个学习练习,因为我真的很想看到这个查询的不同方法。

由于@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)

您可以 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

不需要 DISTINCT(并且始终是危险信号,恕我直言)。

由于仅选择了 a table 中的字段,您可以通过将所有不需要的 table 引用压缩到存在中来避免生成重复项(以及以后需要抑制它们的需要) () - 子查询:


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
        )
        ;