【问题标题】:SQL Query over three different tables对三个不同表的 SQL 查询
【发布时间】:2010-05-17 10:40:15
【问题描述】:

我有三张桌子

CATS
id           name
------------------------------
1            category1
2            category2
3            category3
4            category4


PRODUCT
id           name
------------------------------
1            product1
2            product2



ZW-CAT-PRODUCT
id_cats      id_product
------------------------------
1            1
3            1
4            2

现在我想获取我的产品及其类别

product1 => category1,category3
product2 => category4

有没有办法通过一个 mysql 查询来获取这个数组(或对象或其他东西)? 我尝试了一点 JOINS,但这似乎不是我所需要的,或者?

目前我正在使用 3 个查询(我认为这太多了)。

有什么建议吗?

编辑

另一方面,如果我想获得特定类别的所有产品怎么办? 这也可以在一个查询中完成吗?

【问题讨论】:

    标签: php sql mysql join


    【解决方案1】:

    您可以使用GROUP_CONCAT 在结果中获取单独的列表。

    SELECT p.*, 
           GROUP_CONCAT(c.name SEPARATOR ',') as cats
    FROM PRODUCT p
    LEFT JOIN ZW-CAT-PRODUCT l
      ON l.id_product=p.id
    LEFT JOIN CATS c
      ON c.id=l.id_cats
    GROUP BY p.id
    

    所以基本上,这首先会进行一些连接以获取所有数据。如果您将 GROUP_CONCAT 行替换为 c.name,您将看到每个 product_id/category 对对应的一行。 GROUP BY 告诉它根据产品 ID 对结果进行分组,然后 GROUP_CONCAT(c.name..) 告诉它采用组中出现的所有不同的 c.name 值(因此对于每个产品 ID,因为您按产品分组ID) 并将这些值连接成一个字符串,使用, 作为分隔符。

    所以要让每个类别的所有产品都具有相同的风格,应该是这样的,

    SELECT c.*, 
           GROUP_CONCAT(p.name SEPARATOR ',') as products
    FROM CATS c
    LEFT JOIN ZW-CAT-PRODUCT l
      ON l.id_cats=c.id
    LEFT JOIN PRODUCT p
      ON p.id=l.id_product
    GROUP BY c.id
    

    编辑:仅获取特定类别的产品行(根据评论中的要求),就是这样。

    SELECT p.*
    FROM PRODUCT p
    LEFT JOIN ZW-CAT-PRODUCT l
      ON l.id_product=p.id
    LEFT JOIN CATS c
      ON c.id=l.id_cats
    WHERE c.name='xyz';
    

    【讨论】:

    • 那行得通,哇。即使我真的不知道我做了什么;)我必须更深入地了解这一点。你能检查我上面的编辑吗?
    • 我已经更新了我的答案,试图更好地解释发生了什么,并展示了如何翻转它以对产品等做同样的事情。
    • 好的,谢谢 :) 但是获取一个类别的所有产品我不想让它们用逗号分隔。就像'SELECT * FROM PRODUCTS WHERE CATEGORY ='xyz''。你知道我的意思吗? =/
    • 在这种情况下,它就像“SELECT p.* FROM PRODUCT p LEFT JOIN ZW-CAT-PRODUCT l ON l.id_product=p.id LEFT JOIN CATS c ON c.id=l .id_cats WHERE c.name='xyz';"
    【解决方案2】:

    如果您只需要每个产品的以逗号分隔的类别列表,请查看 MySQL 的 GROUP_CONCAT() 聚合函数:

    SELECT p.*, GROUP_CONCAT(c.name) AS categories
    FROM PRODUCT p
    LEFT JOIN ZW-CAT-PRODUCT cp ON p.id = cp.id_product
    LEFT JOIN CATS c ON cp.id_cats = c.id
    GROUP BY p.id
    

    获取特定类别的所有产品(按类别 ID):

    SELECT p.*
    FROM PRODUCT p
    INNER JOIN ZW-CAT-PRODUCT cp ON p.id = cp.id_product
    WHERE cp.id_cats = 42
    

    相同,但按类别名称:

    SELECT p.*
    FROM PRODUCT p
    INNER JOIN ZW-CAT-PRODUCT cp ON p.id = cp.id_product
    INNER JOIN CATS c ON cp.id_cats = c.id
    WHERE c.name = 'category1'
    

    【讨论】:

    • 我已经用特定类别的所有产品的查询更新了答案
    • 也谢谢你。糟糕的是,我不能双重接受答案;)但赞成
    【解决方案3】:

    是的,您可以将所有 3 个查询放入 1 个查询中,但考虑拥有 3 个巨大的表,我宁愿一个一个地处理它们,而不是在 1 次内获得整个批量。 这需要更长的时间,但(在我看来)对数据更友好。

    【讨论】:

    • 我非常同意这一点,对每个表进行一次查询,而不是试图将它们全部塞在一起,这样会更灵活,更容易解析结果。我通常使用 SQL IN 语句来查找孩子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-15
    • 2017-03-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多