【SQL】常見SQL 行列轉換的方法匯總 - 精華版
- 一、引言
- 二、SQL常見的行列轉換對比
- 1. 行轉列 Pivoting
- 1.1 ??CASE WHEN + 聚合函數??
- 1.2 ??IF + 聚合函數??
- 1.3 ??PIVOT操作符??
- 2.列轉行 Unpivoting
- 2.1 UNION ALL??
- 2.2 ??EXPLODE函數(Hive/Spark)?
- 2.3 ??UNPIVOT操作符??
- 三、對比總結??
- ??四、總結建議??
一、引言
- 近期參加了數據崗位的一些面試(如下圖:近幾年的面試數據),非常多的同學在簡歷上會寫熟悉、精通SQL,但一旦進行原理性(對應數據開發崗)或者實操性(數據分析、數據產品崗)的溝通和測試,往往表現的不盡如人意。所以打算再開一個【SQL】的專欄,分享一些SQL的知識和技巧。
- SQL專題往期內容:
- 【SQL】基于多源SQL 去重方法對比 – 精華版
- 【SQL】常見SQL 行列轉換的方法匯總 - 精華版

二、SQL常見的行列轉換對比
1. 行轉列 Pivoting
1.1 ??CASE WHEN + 聚合函數??
- 實現方式??:CASE條件判斷生成新列,配合MAX/SUM等聚合函數處理數據。
- 優點??:兼容性強,適用于所有支持SQL的數據庫。
- 缺點??:列固定時需手動編寫大量條件,動態列處理困難。
SELECT name,MAX(CASE WHEN skill='語文' THEN 1 ELSE 0 END) AS is_chinese,MAX(CASE WHEN skill='數學' THEN 1 ELSE 0 END) AS is_math
FROM A
GROUP BY name;
| 姓名 | 是否語文 | 是否數學 |
| 張三 | 1 | 0 |
| 張三 | 0 | 1 |
| 姓名 | 是否語文 | 是否數學 |
| 張三 | 1 | 1 |
1.2 ??IF + 聚合函數??
- ??實現方式??:類似CASE WHEN,但語法更簡潔
- 優點??:語法簡化,適合少量固定列。
- 缺點??:同case ,注意事項同case。
SELECT name,MAX(IF(course='語文', score, 0)) AS chinese
FROM A
GROUP BY name;
1.3 ??PIVOT操作符??
- 實現方式??:專用于行轉列的語法,需指定聚合函數和轉換列。
- ??優點??:語法簡潔,邏輯清晰。
- 缺點??:僅支持部分數據庫(如SQL Server、Oracle),動態列需結合動態SQL。
SELECT * FROM Sales
PIVOT (SUM(Amount) FOR Month IN ([Jan-22], [Feb-22])) AS PivotTable;
2.列轉行 Unpivoting
2.1 UNION ALL??
- 實現方式??:將多列拆分為多個SELECT子查詢后合并。
- ??優點??:兼容性好,適用于所有數據庫。
- 缺點??:代碼冗余,列多時維護困難。
SELECT name, '語文' AS subject, is_chinese AS value FROM A WHERE is_chinese = 1
UNION ALL
SELECT name, '數學' AS subject, is_math FROM B WHERE is_math = 1
2.2 ??EXPLODE函數(Hive/Spark)?
- ??實現方式??:將數組或拆分后的字符串轉換為多行。
- 優點??:簡潔高效,適合處理數組或分隔字符串。
- 缺點??:僅適用于支持EXPLODE的大數據平臺(如Hive)。
SELECT name, subject FROM B
LATERAL VIEW EXPLODE(SPLIT(subject, ',')) tmp AS subject;
2.3 ??UNPIVOT操作符??
- 實現方式??:專用于列轉行的語法。
- ??優點??:語法直觀,邏輯清晰。
- 缺點??:僅支持部分數據庫(如SQL Server)。
SELECT name, subject, value FROM A
UNPIVOT (value FOR subject IN (is_chinese, is_math)) AS UnpivotTable;
三、對比總結??
方法 | 適用場景 | 優勢 | 劣勢 |
---|
CASE WHEN | 簡單固定列的行轉列 | 所有數據庫支持,兼容性強 | 代碼冗余,動態列處理困難 |
PIVOT/UNPIVOT | 支持該語法的數據庫 | 語法簡潔,邏輯清晰 | 動態列需結合動態SQL,兼容性差 |
UNION 系列 | 列轉行且列數較少 | 所有數據庫支持,簡單通用 | 代碼冗余,維護成本高 |
EXPLODE | 大數據平臺中的數組或字符串拆分 | 高效簡潔 | 環境受限,僅Hive/Spark等 |
??四、總結建議??
類型 | 優先級 |
---|
行轉列?? | PIVOT(若數據庫支持) > CASE WHEN |
??列轉行 | UNPIVOT / EXPLODE > UNION ALL |
動態列處理 | 結合應用層邏輯生成SQL(如Java/Python拼接),或使用存儲過程(偏應用場景,故這里不介紹) |
- 具體選擇哪種類型實現,需要根據業務場景下,對應的數據庫類型、數據量、列是否固定等等因素綜合判斷,從而選擇相對較優的解。