MySQL行转列实现:将company_name值作为列名按item分组
在MySQL中实现行转列(按item分组,供应商作为列展示totalPrice)
静态列解决方案(已知供应商列表)
如果供应商名称固定(比如示例中的EGB Trading和Goodluck Trading),可以用条件聚合实现行转列:
SELECT ac.quantity, ac.unit, ac.item, MAX(CASE WHEN s.company_name = 'EGB Trading' THEN sp.totalPrice END) AS `EGB Trading`, MAX(CASE WHEN s.company_name = 'Goodluck Trading' THEN sp.totalPrice END) AS `Goodluck Trading`, ac.totalcost FROM tbl_addcolumn ac INNER JOIN tbl_supplierprice sp ON ac.id = sp.itemName INNER JOIN tbl_supplier s ON sp.fk_supplierId = s.id WHERE s.pr_no = '2023-03-0001' GROUP BY ac.quantity, ac.unit, ac.item, ac.totalcost ORDER BY ac.item ASC;
说明:
- 用
CASE WHEN配合MAX聚合函数,将每个供应商的totalPrice映射到对应列 GROUP BY包含quantity、unit、item、totalcost,确保同一分组内这些字段取值一致- 含空格的列名需要用反引号
`包裹
执行后得到结果:
| quantity | unit | item | EGB Trading | Goodluck Trading | totalcost |
|---|---|---|---|---|---|
| 5 | rim | A4 bond paper | 300 | 500 | 750 |
| 50 | piece | black pen | 300 | 200 | 250 |
| 50 | piece | blue pen | 100 | 200 | 250 |
| 50 | piece | red pen | 100 | 200 | 250 |
动态列解决方案(供应商不固定)
如果供应商数量会变化,用动态SQL自动生成列名:
SET @sql = NULL; -- 拼接所有唯一供应商对应的列语句 SELECT GROUP_CONCAT( DISTINCT CONCAT( 'MAX(CASE WHEN s.company_name = ''', s.company_name, ''' THEN sp.totalPrice END) AS `', s.company_name, '`' ) ) INTO @sql FROM tbl_supplier s INNER JOIN tbl_supplierprice sp ON s.id = sp.fk_supplierId INNER JOIN tbl_addcolumn ac ON sp.itemName = ac.id WHERE s.pr_no = '2023-03-0001'; -- 拼接完整SQL SET @sql = CONCAT( 'SELECT ac.quantity, ac.unit, ac.item, ', @sql, ', ac.totalcost FROM tbl_addcolumn ac INNER JOIN tbl_supplierprice sp ON ac.id = sp.itemName INNER JOIN tbl_supplier s ON sp.fk_supplierId = s.id WHERE s.pr_no = ''2023-03-0001'' GROUP BY ac.quantity, ac.unit, ac.item, ac.totalcost ORDER BY ac.item ASC;' ); -- 执行动态SQL PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
说明:
- 先通过
GROUP_CONCAT动态生成每个供应商的条件聚合片段 - 将片段拼接到完整SQL语句中
- 用
PREPARE和EXECUTE执行动态生成的SQL
内容的提问来源于stack exchange,提问作者newbie
相关产品推荐
相关产品推荐

