SQL按同一列中的多个项目进行过滤

标签 sql postgresql filter

我在 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 代码总是更可取。

最佳答案

有关性能详细信息,请参阅我博客中的这篇文章:


解决方法如下:

  • 适用于任意数量的类别

  • COUNTGROUP 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/

相关文章:

r - 使用另一个条件过滤某些值和多个先前行

java - 多种类型的过滤器<Object>

sql - 如何在 MySQL 中组合两个具有不同列的 SQL 查询而不组合其结果行

sql - oracle地理编码查询真的很慢,我如何优化动态字段?

postgresql - 如何在 postgresql 中创建和存储对象数组

postgresql - 如何在没有警告停止的情况下在postgres中执行真空命令?

database - "relation not found"在 Eclipse Hibernate 应用程序中使用 Postgres

mysql - MySQL中外键与复合主键的关系

mysql - 在 MySQL 中构建查询来查找客户名称

c - 如何用karplus strong算法实现插值延迟线和全通滤波器?