如何将MySQL内连接结果从行转换为列进行分组

10
也许我的问题不是很清楚,请允许我解释一下:我需要获取所有用户的列表,以及相应的客户号码/批发商组合,每个客户有1到4个不同的客户号码/批发商组合。
在我的数据库中,有两个表。
USERS
id | name
---------
1  | a
2  | b

CLIENT_NUMBERS
id | user_id | number | wholesaler
----------------------------------
1  | 1       | ac1    | aw1
2  | 1       | ac2    | aw2
3  | 2       | bc1    | bw1

使用简单的INNER JOIN,我得到了客户行的重复,每个相应的客户号码/批发商都有一个副本

我已经在这个查询中使用GROUP_CONCAT解决了结果问题:

SELECT a.id AS user_id, a.name AS Name 
GROUP_CONCAT(b.client_no, ', ', b.wholesaler SEPARATOR '; ') AS client_no_wholesaler 
FROM users AS a 
INNER JOIN client_numbers AS b ON a.id = b.user_id 
GROUP BY ID

user_id | name | client_no_wholesaler
--------------------------------------------
1       | a    |  ac1, aw1; ac2, aw2 
2       | b    |  bc1, bw1

到目前为止,一切都很好,但我需要将客户号码/批发商组合 "分解" 成不同的列,以便我的结果看起来像这样:

user_id | name | client_no_wholesaler1 | client_no_wholesaler2 | ...up to 4
----------------------------------------------------------------------------
1       | a    |  ac1, aw1             | ac2, aw2              |
2       | b    |  bc1, bw1             |                       |

使用简单的PHP explode获取查询结果后再执行此操作不是一个选择,因为我正在使用一个类来生成XLS文件,其基于我的查询结果列,任何想法将不胜感激。

1个回答

5
你希望的通常称为“pivot”。 以下是在SQL中编码所需的额外联接每个额外列的方法:
SELECT
    a.id AS user_id,
    a.name AS Name,
    CONCAT(b1.client_no, ', ', b1.wholesaler) AS client_no_wholesaler1,
    CONCAT(b2.client_no, ', ', b2.wholesaler) AS client_no_wholesaler2,
    CONCAT(b3.client_no, ', ', b3.wholesaler) AS client_no_wholesaler3,
    CONCAT(b4.client_no, ', ', b4.wholesaler) AS client_no_wholesaler4
FROM users AS a
JOIN client_numbers AS b1 ON b1.user_id = a.id
LEFT JOIN client_numbers AS b2 ON b2.user_id = a.id and b2.id > b1.id
LEFT JOIN client_numbers AS b3 ON b3.user_id = a.id and b3.id > b2.id
LEFT JOIN client_numbers AS b4 ON b4.user_id = a.id and b4.id > b3.id
GROUP BY 1, 2

请注意,额外的连接通过在附加连接的ON子句中添加一个逐渐增加的id条件来避免重复连接。如果id不是合适的排序列,请选择其他东西来分隔连接。

“Pivot” 我今天学到了新东西,非常感谢,你的查询按照我需要的方式工作。 - a59327424

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接