【问题标题】:mysql join on product category multiple relation querymysql加入产品类别多关系查询
【发布时间】:2017-11-27 19:18:02
【问题描述】:

我有如下三个表,每个产品可能属于多个类别。

产品表作为 P
1.身份证
2. 姓名

类别表为 C
1.身份证 2. 姓名

关系表作为 R 1.身份证
2. P_ID
3. C_ID

现在我想获取产品表中所有产品的列表,以及它们所属的类别名称显示。

如何编写此查询?

我可以从同一个查询中获取类别 ID,但不知道如何获取所有名称。这是我尝试过的。

select p.*,y.* 
  from p 
  left join (select p_id,group_concat(c_id) as category_ids 
               from relation group by p_id) as y on p.id=y.p_id

【问题讨论】:

  • 只是提一下...您通常不希望将所有(ID,名称,...)都塞进这样的字符串中,特别是如果您打算稍后解析它。除其他问题外,现在您无法可靠地使用包含逗号的类别名称。
  • 感谢您提醒我这一点,我将使用分隔符而不是逗号。
  • 您可能选择的大多数其他分隔符都会让您遇到同样的问题。如果您坚持在一个字段中将内容连接在一起(这只是自找麻烦,IMO),那么您的分隔符必须是永远不会合理出现在类别 ID/名称中的分隔符(例如,我可能建议换行),你需要采取措施确保它永远不会发生。

标签: mysql join


【解决方案1】:

执行两个 JOIN 操作(到关系表,并从那里到包含类别名称的表)并将结果提供给您的聚合函数 (GROUP_CONCAT)

SELECT P.Name, GROUP_CONCAT(DISTINCT C.Name ORDER BY C.Name SEPARATOR '|') categories
  FROM Product P
  LEFT JOIN Relation R ON P.ID = R.P_ID
  LEFT JOIN Category C ON R.C_ID = C.ID
 GROUP BY P.ID, P.Name

这将为每个产品提供一行,类别由| 分隔。

这使用了 LEFT JOIN 操作,因此它不会抑制没有类别的产品。

【讨论】:

    【解决方案2】:
    Select P.Name, C.Name
      From RELATION R Inner Join PRODUCT P
      On R.P_ID=P.Id
      Inner Join Category C
      On C.Id=R.C_ID
    

    此查询将为您提供所有产品及其对应的类别。

    我想稍微解释一下Inner Join和Left Join的区别。
    如果我们以 2 个表为例:
    TA(idA,描述)和 TB(idB,idA,描述)。

    Select TA.description, TB.description
    From TA Inner Join TB On TA.IdA = TB.IdA
    

    将只获取 TA 中与 TB 中对应的行。
    另一边,

    Select TA.description, TB.description
    From TA Left Join TB On TA.IdA = TB.IdA
    

    将获取 TA 的所有行,如果 TA 中的行在 TB 中没有对应的行,则该行的 TB.description 将为 NULL。

    希望这会有所帮助!

    【讨论】:

    • 首先谢谢!但是这个查询会生成一个包含重复产品的列表,例如,如果一个产品属于 3 个类别,它将在列表中列出 3 次。
    • 是的,你是对的,它将被列出 3 次,分为 3 个不同的类别。我认为这就是你想要的。
    猜你喜欢
    • 2021-03-12
    • 1970-01-01
    • 2015-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多