代码之家  ›  专栏  ›  技术社区  ›  Christian P.

仅提取与联接表(SQL)中的所有条目匹配的行

  •  2
  • Christian P.  · 技术社区  · 16 年前

    我有以下五张桌子:

    • 网络服务提供商
    • 产品
    • 连接
    • 阿登
    • 加载项/产品(多对多关系的透视表)。

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

    我感兴趣的结果是与所列加载项的每个连接(为此,我使用mysql的group_concat,以逗号分隔加载项的列表) 名称 字段)。此操作正常,查询如下所示:

    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
    

    我正在使用左联接,因为产品可能根本没有附加组件。

    我的问题是,可以选择列出连接必须具有的一些加载项,以加载项ID列表的形式显示,如(1,14237)。如果我在join语句中将它作为附加条件放入( 和pa.addon_id in(…) ,它将返回只包含一个列出的加载项的所有连接,但不一定全部返回。

    有什么方法可以将所有连接作为 最低限度 所有的插件(它们也可以有附加的)都通过SQL吗?

    2 回复  |  直到 14 年前
        1
  •  2
  •   devio    16 年前
    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
  •  0
  •   Tony Andrews    16 年前

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