萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

SQL 行轉列/列轉行兩大核心技法:CASE WHEN 與 PIVOT 實戰

測試資料準備

CREATE DATABASE tmp; USE tmp;
CREATE TABLE Scores (
    ID INT IDENTITY(1,1) PRIMARY KEY,
    Student VARCHAR(20),
    Subject VARCHAR(30),
    Score FLOAT
);
INSERT INTO Scores (Student, Subject, Score) VALUES
('test001','語文',90),('test001','英語',85),
('text002','語文',90),('text002','英語',80),
('test003','語文',95),('test003','英語',85);

方法一:CASE WHEN 聚合(通用、全版本支援)

SELECT Student AS 姓名,
       MAX(CASE Subject WHEN '語文' THEN Score ELSE 0 END) AS 語文,
       MAX(CASE Subject WHEN '英語' THEN Score ELSE 0 END) AS 英語
FROM Scores
GROUP BY Student
ORDER BY Student;

原理:CASE 將行值轉為列,MAX 聚合去除 NULL,GROUP BY 縮列。

方法二:PIVOT 運算子(SQL Server 2005+)

SELECT Student AS 姓名,
       AVG(語文) AS 語文,
       AVG(英語) AS 英語
FROM Scores
PIVOT ( AVG(Score) FOR Subject IN (語文, 英語) ) AS NewScores
GROUP BY Student
ORDER BY Student ASC;

限制:
・ 僅支援 SQL Server 2005 以上。
・ IN 列表需硬編碼,動態列需動態 SQL 拼接。
・ 聚合函數固定(SUM/AVG/MAX/MIN/COUNT)。

列轉行:UNPIVOT / CROSS APPLY

-- SQL Server UNPIVOT
SELECT Student, Subject, Score
FROM (
    SELECT Student, 語文, 英語 FROM PivotedTable
) src
UNPIVOT (Score FOR Subject IN (語文, 英語)) AS upvt;

MySQL/PostgreSQL 替代方案

無原生 PIVOT,採用 CASE WHEN 或動態 SQL 拼接。
PostgreSQL 9.4+ 可用 crosstab (tablefunc 擴充)。

效能建議

  • 行轉列前先過濾/聚合縮小資料集。
  • 動態列場景優先考慮應用層處理,減少資料庫動態 SQL 風險。
  • 大量資料轉置考慮物化視圖或 OLAP 引擎(ClickHouse、Druid)。
copyright © 萬盛學電腦網 all rights reserved