如何在MySQL中将指定列转换为行(列转行操作)
MySQL列转行实现方案
原表结构与数据
| prod_date | model | assembly | AM_Output | PM_Output | AM WHrs | PM WHrs |
|---|---|---|---|---|---|---|
| 2023-08-01 | A | FAN | 2112 | 0 | 10.75 | 0 |
| 2023-08-02 | A | FAN | 1440 | 978 | 10.75 | 10.75 |
| 2023-08-03 | A | FAN | 1134 | 0 | 10.75 | 0 |
目标表结构与数据
| prod_date | model | assembly | Shift_Out | Output | WHrs |
|---|---|---|---|---|---|
| 2023-08-01 | A | FAN | AM | 2112 | 10.75 |
| 2023-08-02 | A | FAN | AM | 1440 | 10.75 |
| 2023-08-03 | A | FAN | AM | 1134 | 10.75 |
| 2023-08-01 | A | FAN | PM | 0 | 0 |
| 2023-08-02 | A | FAN | PM | 978 | 10.75 |
| 2023-08-03 | A | FAN | PM | 0 | 0 |
实现方法
方法1:UNION ALL(兼容所有MySQL版本)
这是最通用的方案,分别提取AM、PM班次的数据后合并结果:
-- 提取AM班次数据 SELECT prod_date, model, assembly, 'AM' AS Shift_Out, AM_Output AS Output, `AM WHrs` AS WHrs FROM your_table_name UNION ALL -- 提取PM班次数据 SELECT prod_date, model, assembly, 'PM' AS Shift_Out, PM_Output AS Output, `PM WHrs` AS WHrs FROM your_table_name -- 可选:按日期和班次排序 ORDER BY prod_date, Shift_Out;
注意:
- 替换
your_table_name为实际表名;如果是多表左连接的结果,直接把整个左连接语句用括号包裹替换掉your_table_name - 因列名包含空格,
AM WHrs和PM WHrs需要用反引号`包裹
方法2:CROSS JOIN + CASE(MySQL 5.7+,灵活扩展)
通过生成班次列表,用CASE语句匹配对应列的值:
SELECT t.prod_date, t.model, t.assembly, s.shift AS Shift_Out, CASE s.shift WHEN 'AM' THEN t.AM_Output WHEN 'PM' THEN t.PM_Output END AS Output, CASE s.shift WHEN 'AM' THEN t.`AM WHrs` WHEN 'PM' THEN t.`PM WHrs` END AS WHrs FROM your_table_name t CROSS JOIN ( SELECT 'AM' AS shift UNION ALL SELECT 'PM' AS shift ) s ORDER BY t.prod_date, s.shift;
方法3:LATERAL JOIN(MySQL 8.0.14+,简洁高效)
利用LATERAL JOIN直接为每行生成两条班次记录:
SELECT t.prod_date, t.model, t.assembly, s.* FROM your_table_name t JOIN LATERAL ( SELECT 'AM' AS Shift_Out, t.AM_Output AS Output, t.`AM WHrs` AS WHrs UNION ALL SELECT 'PM' AS Shift_Out, t.PM_Output AS Output, t.`PM WHrs` AS WHrs ) s ORDER BY t.prod_date, s.Shift_Out;
内容的提问来源于stack exchange,提问作者silver
相关产品推荐
相关产品推荐

