如何在没有子查询的情况下表达这个 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
)
;
我有一个包含 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
)
;