最近正准備面試,所以本來不怎么熟悉的SQL語句迫切需要練習,學習一下
在此感謝 笨鳥先飛-天道酬勤 大佬的博客:https://blog.csdn.net/dehu_zhou/article/details/52881587
在題17:按平均成績從高到低顯示所有學生的所有課程的成績以及平均成績
SELECT a.* ,SUM(CASE WHEN b.Cid='01' THEN b.score ELSE 0 END) AS s01 ,SUM(CASE WHEN b.Cid='02' THEN b.score ELSE 0 END) AS s02 ,SUM(CASE WHEN b.Cid='03' THEN b.score ELSE 0 END) AS s03 ,AVG(ifnull(b.score,0)) as avs FROM Student a LEFT JOIN SC b ON a.Sid=b.Sid GROUP BY 1,2,3,4 ORDER BY avs DESC ;
最終的結果如下:
在這里感覺到了疑惑,為啥07的平均成績沒有計算s01這個值呢,導致最終結果與我想的不符(按3取平均值)
百思不得其解
后來感謝群內大佬的解答
原因在於:
AVG()函數統計的是表中的數據,對於SC表而言,需要計算的score值只有2個,所以即便在后續的join語句中,產生了null值,並置為0.在這里也是按SC表中的2個數值計算,而非3個數值;
解決辦法:
方法1:再套一層查詢,將結果作為臨時表,對臨時表字段進行統計
select t.*, round((s01+s02+s03)/3,2) as avs from ( SELECT a.* ,SUM(CASE WHEN b.Cid='01' THEN b.score ELSE 0 END) AS s01 ,SUM(CASE WHEN b.Cid='02' THEN b.score ELSE 0 END) AS s02 ,SUM(CASE WHEN b.Cid='03' THEN b.score ELSE 0 END) AS s03 FROM Student a LEFT JOIN SC b ON a.Sid=b.Sid GROUP BY 1,2,3,4 ) t ORDER BY avs desc;
返回結果:
方法2:根據課程表,補全課程信息
select * from Student t LEFT JOIN ( select a.Sid ,max(case when a.Cid='01' THEN a.score ELSE 0 END) as s01 ,max(case when a.Cid='02' THEN a.score ELSE 0 END) as s02 ,max(case when a.Cid='03' THEN a.score ELSE 0 END) as s03 ,round(avg(case when a.score is null then 0 else a.score end),2) as avs from SC a group BY a.Sid ) t1 on t.Sid = t1.Sid ;
返回結果: