原始表:
SNAME CNAME SCORE
小李 JAVA 98
小李 mysql 78
小明 JAVA 88
小明 mysql 88
目標輸出:
sname JAVA MYSQL
小李 優秀 普通
小明 普通 普通
分級規則:>平均分+20→優秀,>平均分+10→良好,=平均分→普通,<平均分→一般,<平均分-10→較差。
CASE WHEN 對每門課分數分級。MAX(CASE...) 實現行轉列。WITH avg_scores AS (
SELECT CNAME, AVG(SCORE) AS avg_score
FROM scores
GROUP BY CNAME
)
SELECT
s.SNAME,
MAX(CASE WHEN s.CNAME = 'JAVA' THEN
CASE
WHEN s.SCORE > a.avg_score + 20 THEN '優秀'
WHEN s.SCORE > a.avg_score + 10 THEN '良好'
WHEN s.SCORE = a.avg_score THEN '普通'
WHEN s.SCORE < a.avg_score - 10 THEN '較差'
ELSE '一般'
END
END) AS JAVA,
MAX(CASE WHEN s.CNAME = 'mysql' THEN
CASE
WHEN s.SCORE > a.avg_score + 20 THEN '優秀'
WHEN s.SCORE > a.avg_score + 10 THEN '良好'
WHEN s.SCORE = a.avg_score THEN '普通'
WHEN s.SCORE < a.avg_score - 10 THEN '較差'
ELSE '一般'
END
END) AS MYSQL
FROM scores s
JOIN avg_scores a ON s.CNAME = a.CNAME
GROUP BY s.SNAME;
WITH 子句(MySQL 8.0+)計算各課平均分,舊版本可用子查詢或臨時表。MAX(CASE...) 配合 GROUP BY SNAME 將多行壓縮為一行多列。CASE 實現分級邏輯,條件順序自高至低,ELSE 兜底。MySQL 5.7 及以下無 WITH,改用派生表:
SELECT ... FROM scores s
JOIN (SELECT CNAME, AVG(SCORE) avg_score FROM scores GROUP BY CNAME) a
ON s.CNAME = a.CNAME
GROUP BY s.SNAME;