我在 SQL 中有两个表,一个包含一个项目,另一个包含项目所属的类别,即 JOIN 大致如下所示:
Project | Category
--------+---------
Foo | Apple
Foo | Banana
Foo | Carrot
Bar | Apple
Bar | Carrot
Qux | Apple
Qux | Banana
(显然,字符串被更高级范式中的 ID 替换,但您明白了。)
我想要做的是允许过滤,这样用户可以选择任意数量的类别,结果将被过滤到属于所有选定类别的项目。例如,如果用户选择类别“Apple”和“Banana”,则会显示项目“Foo”和“Qux”。如果用户选择类别“Apple”、“Banana”和“Carrot”,则只会显示“Foo”项目。
我尝试的第一件事是一个简单的 SELECT DISTINCT Project FROM ... WHERE Category = 'Apple' AND Category = 'Banana',但这当然行不通,因为 Apple 和 Banana 出现在任何常见项目的两个不同行。
GROUP BY 和 HAVING 对我没有任何好处,所以请告诉我:是否有一种明显的方法可以做到这一点而我错过了,或者它真的很复杂以至于我不得不求助于递归加入?
顺便说一句,这是在 PostgreSQL 中,但当然,在可能的情况下,标准 SQL 代码总是更可取。
最佳答案
有关性能详细信息,请参阅我博客中的这篇文章:
解决方法如下:
适用于任意数量的类别
比
COUNT
和GROUP BY
更有效,因为它只检查一次任何项目/类别对的存在,而不计算。
SELECT *
FROM (
SELECT DISTINCT Project
FROM mytable
) mo
WHERE NOT EXISTS
(
SELECT NULL
FROM (
SELECT 'Apple' AS Category
UNION ALL
SELECT 'Banana'
UNION ALL
SELECT 'Carrot'
) list
WHERE NOT EXISTS
(
SELECT NULL
FROM mytable mii
WHERE mii.Project = mo.Project
AND mii.Category = list.Category
)
)
关于SQL按同一列中的多个项目进行过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1330221/