MySQL--關於MySQL練習過程中遇到的AVG()函數處理空值的問題


最近正准備面試,所以本來不怎么熟悉的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
;

  返回結果:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM