MySQL行列转化
初始化表结构:
CREATE TABLE `student_scores` (
`student_id` int NOT NULL,
`student_name` varchar(50) DEFAULT NULL,
`math_score` int DEFAULT NULL,
`english_score` int DEFAULT NULL,
`science_score` int DEFAULT NULL,
PRIMARY KEY (`student_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
INSERT INTO student_scores (student_id, student_name, math_score, english_score, science_score) VALUES
(1, 'Alice', 85, 90, 78),
(2, 'Bob', 76, 88, 92),
(3, 'Charlie', 90, 85, 80);
查询表数据:
行转化为列:
由于不是我们想要的格式,我们将其转化为列式结构:
-- 行数转化为列
SELECT student_id, student_name, 'Math' AS subject, math_score AS score FROM student_scores
UNION ALL
SELECT student_id, student_name, 'English' AS subject, english_score AS score FROM student_scores
UNION ALL
SELECT student_id, student_name, 'Science' AS subject, science_score AS score FROM student_scores;
执行结果:
列转化为行:
将其作为一张临时表,对其进行行列转化:
select student_id,student_name,
MIN(Case when subject = 'Math' then score end ) as math_score,
MIN(case when subject = 'English' then score end )as english_score,
MIN(case when subject = 'Science' then score end )as science_score
from (
SELECT student_id, student_name, 'Math' AS subject, math_score AS score FROM student_scores
UNION ALL
SELECT student_id, student_name, 'English' AS subject, english_score AS score FROM student_scores
UNION ALL
SELECT student_id, student_name, 'Science' AS subject, science_score AS score FROM student_scores
) AS unpivoted
GROUP BY unpivoted.student_id,unpivoted.student_name
执行结果:
扩展:
union 与 union all区别
-
UNION:会自动去除合并结果集中的重复记录,只返回唯一的记录。
-
UNION ALL:会返回所有记录,包括重复的记录。