【问题标题】:MySQL WHERE filter based on subquery in SELECTMySQL WHERE 过滤器基于 SELECT 中的子查询
【发布时间】:2021-08-12 21:51:19
【问题描述】:

我有一个名为 Records 的表格,用于显示产品。我还有一个名为 Categories 的表格,其中显示了每个单独产品的类别(如果存在的话)。

Categories 表的结构类似于:

id    category_id
--    -----------
1     1
1     3
3     1
3     2
5     4

我为提取记录 ID 和类别 ID 而运行的查询是:

SELECT 
    Records.id,
    (SELECT
        GROUP_CONCAT(C.category_id)
    FROM `Categories` C
    WHERE Records.id = C.id) AS 'CategoryName'
FROM 
    Records

输出将返回:

id    CategoryName
--    ------------
1     1,3
2     NULL
3     1,2
4     4
5     NULL

我的网站有一个区域,用户可以在其中按类别过滤记录。假设用户想要过滤类别 = 1 或 2。我想我只是添加 WHERE FIND_IN_SET(1,CategoryName) OR FIND_IN_SET(2,CategoryName) 但这不起作用,因为 MySQL execution orderCategoryName 列尚不存在。

过滤category_id 的最佳方法是什么?类别的输入将用逗号分隔,但我可以使用 PHP 到 explode() 字符串来分隔它们。

【问题讨论】:

    标签: php mysql filter subquery


    【解决方案1】:

    您可以使用将Records 连接到CategoriesLEFT 连接重写查询:

    SELECT r.id,
           GROUP_CONCAT(c.category_id) AS CategoryName
    FROM Records r LEFT JOIN Categories c
    ON c.id = r.id
    GROUP BY r.id
    

    如果您想使用相同的查询进行过滤,您只需在末尾添加 HAVING 子句:

    HAVING FIND_IN_SET(1, CategoryName) OR FIND_IN_SET(2, CategoryName)
    

    或者,你可以先过滤再聚合:

    SELECT r.id,
           GROUP_CONCAT(c.category_id) AS CategoryName
    FROM Records r INNER JOIN Categories c
    ON c.id = r.id
    WHERE c.category_id IN (1, 2)
    GROUP BY r.id
    

    【讨论】:

    • 它不会是INNER JOIN,因为类别并不总是匹配。但是使用LEFT JOIN 效果很好。
    • @Bijan 2nf 查询应该是一个内部联接,因为它仅用于过滤(即使使用 LEFT 联接,由于 WHERE 子句,它实际上也是一个内部联接)。第一个带有 LEFT 连接的查询可以在没有 HAVING 子句的情况下用于获取所有行并使用 HAVING 子句进行过滤。
    猜你喜欢
    • 2020-06-03
    • 2016-01-16
    • 1970-01-01
    • 2013-09-25
    • 1970-01-01
    • 2020-10-22
    • 2020-01-06
    • 2021-12-22
    • 2011-10-20
    相关资源
    最近更新 更多