【问题标题】:Many To Many Table Join With Pivot使用 Pivot 连接多对多表
【发布时间】:2011-05-25 02:10:28
【问题描述】:

我目前有两个类似于usersprograms 的表,它们通过link 表通过多对多关系链接。

mysql> select * from users;
+----+----------+
| id | name     |
+----+----------+
|  1 | Jonathan |
|  2 | Little   |
|  3 | Annie    |
|  4 | Bob      |
+----+----------+
4 rows in set (0.00 sec)

mysql> select * from programs;
+----+----------------------+
| id | name                 |
+----+----------------------+
|  1 | Microsoft Word       |
|  2 | Microsoft Excel      |
|  3 | Microsoft PowerPoint |
+----+----------------------+
3 rows in set (0.00 sec)

mysql> select * from link;
+---------+------------+
| user_id | program_id |
+---------+------------+
|       1 |          1 |
|       1 |          2 |
|       1 |          3 |
|       2 |          2 |
|       3 |          1 |
|       3 |          4 |
+---------+------------+
6 rows in set (0.00 sec)

我了解如何加入表格并返回此类结果:

mysql> select users.name, programs.name from linker
    -> join users on users.id = linker.user_id
    -> join programs on programs.id = linker.program_id;
+----------+----------------------+
| name     | name                 |
+----------+----------------------+
| Jonathan | Microsoft Word       |
| Jonathan | Microsoft Excel      |
| Jonathan | Microsoft PowerPoint |
| Little   | Microsoft Excel      |
| Annie    | Microsoft Word       |
+----------+----------------------+

但我真正要寻找的是更复杂一点:

+----------+-----------------------------------------------------+
| name     | name                                                |
+----------+-----------------------------------------------------+
| Jonathan | Microsoft Word,Microsoft Excel,Microsoft PowerPoint |
| Little   | Microsoft Excel                                     |
| Annie    | Microsoft Word                                      |
+----------+-----------------------------------------------------+

我假设某处的命令中有一个GROUP_CONCAT(),但我似乎无法阻止结果看起来像这样:

mysql> select users.name, group_concat(programs.name) from linker
    -> join users on users.id = linker.user_id
    -> join programs on programs.id = linker.program_id;
+----------+------------------------------------------------------------------------------------+
| name     | group_concat(programs.name)                                                        |
+----------+------------------------------------------------------------------------------------+
| Jonathan | Microsoft Word,Microsoft Excel,Microsoft PowerPoint,Microsoft Excel,Microsoft Word |
+----------+------------------------------------------------------------------------------------+

谁能指出我正确的方向?

【问题讨论】:

    标签: mysql many-to-many pivot


    【解决方案1】:

    你需要指定一个DISTINCT,即

    select users.name, group_concat( DISTINCT programs.name)
    

    请参阅 MySQL 文档 here

    尝试将您的查询更改为:

    SELECT users.name, group_concat(programs.name) 
    from users
    LEFT JOIN linker on linker.user_id = users.id
    LEFT JOIN programs on linker.program_id = programs.id
    GROUP BY users.id
    

    这将为您提供一个null,用于任何没有与之关联的程序的用户。要过滤掉它们,只需添加 WHERE programs.id IS NOT NULL

    【讨论】:

    • 这消除了重复值,但也将结果限制在第一行。
    • 更新了答案 - 试试上面的查询。
    • 啊,我错过了GROUP BY 子句。非常感谢!
    【解决方案2】:
    SELECT users.name, group_concat(programs.name) from linker
    INNER JOIN users on linker.user_id = users.id
    INNER JOIN programs on linker.program_id = programs.id
    GROUP BY users.id;
    

    【讨论】:

    • 这仍然只返回第一行,包括额外的(重复的)程序名称。我认为无论顺序如何,平等测试的评估方式都相同。
    • @kpsfire 啊哈!是的,你是对的,我的错,当你使用左连接或右连接时,顺序很重要。
    猜你喜欢
    • 1970-01-01
    • 2012-09-10
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-29
    相关资源
    最近更新 更多