【问题标题】:Fetching only rows that match all entries in a joined table (SQL)仅获取与联接表中的所有条目匹配的行 (SQL)
【发布时间】:2010-09-24 22:15:33
【问题描述】:

我有以下五张表:

  • 互联网服务供应商
  • 产品
  • 连接
  • 插件
  • AddOn/Product(多对多关系的数据透视表)。

每个产品都链接到一个 ISP,每个连接都列出一个产品。通过使用数据透视表(只有两个字段,一个用于产品 ID,一个用于 AddOn ID),每个产品都可以有多个附加组件。

我感兴趣的结果是与列出的插件的每个连接(为此,我使用 MySQL 的 GROUP_CONCAT 来制作插件 name 字段的逗号分隔列表)。这工作正常,查询看起来像这样:

SELECT i.name AS ispname, i.img_link, c.download, c.upload, c.monthly_price, c.link, 
GROUP_CONCAT(a.name) AS addons, SUM(pa.monthly_fee) AS addon_price
FROM isp i JOIN product p ON i.id = p.isp_id
JOIN `connection` c ON p.id = c.product_id LEFT JOIN product_addon pa ON pa.product_id = p.id AND pa.forced = 0
LEFT JOIN addon a ON pa.addon_id = a.id GROUP BY c.id

我正在使用 LEFT JOINS,因为产品可能根本没有插件。

我的问题是可以选择列出的连接必须具有的一些插件,以插件 ID 列表的形式显示,例如 (1,14,237)。如果我将它作为附加条件放入 JOIN 语句(AND pa.addon_id IN (...)),它将返回仅具有列出的插件之一的所有连接,但不一定全部。

有没有办法通过 SQL 返回所有最少具有所有插件(它们也可以有附加)的连接?

【问题讨论】:

    标签: sql join


    【解决方案1】:
    GROUP BY set-of-column
    HAVING SUM(CASE WHEN ISNULL(pa.addon_id, 0) IN (1,14,237) THEN 1 ELSE 0 END) = 3
    

    【讨论】:

      【解决方案2】:

      您可以添加到 WHERE 子句:

      AND NOT EXISTS (SELECT NULL FROM addon a2
                      WHERE  a2.addon_id IN (1,14,237)
                      AND NOT EXISTS
                      ( SELECT NULL
                        FROM   product_addon pa2
                        WHERE  pa2.addon_id = a2.addon_id
                        AND    pa2.product_id = p.product_id
                      )
                     )
      

      或等效:

      AND NOT EXISTS (SELECT NULL FROM addon a2
                      LEFT JOIN product_addon pa2
                        ON pa2.addon_id = a2.addon_id
                       AND pa2.product_id = p.product_id
                      WHERE a2.addon_id IN (1,14,237)
                      AND   pa2.product_id IS NULL
                      )
                     )
      

      【讨论】:

        猜你喜欢
        • 2014-02-19
        • 2019-02-11
        • 1970-01-01
        • 1970-01-01
        • 2014-08-04
        • 2012-12-20
        • 2018-10-12
        • 1970-01-01
        • 2017-12-20
        相关资源
        最近更新 更多