oracle 计算中位数,SQL 如何计算每个分组的中位数
中位數(shù)是指一組數(shù)據(jù)排序以后,位于中間位置的數(shù)據(jù)值。如果數(shù)據(jù)個(gè)數(shù)是奇數(shù),中位數(shù)就是最中間位置那個(gè)值;如果是偶數(shù),則是中間位置那兩個(gè)數(shù)的平均值。
怎么查詢出數(shù)據(jù)分組以后每個(gè)組的中位數(shù)呢?
用SQL來解決這個(gè)問題是很有難度的!
SQL的集合是無序的,沒有數(shù)據(jù)位置的概念,需要人為地造出行號,但是要對各分組獨(dú)立編行號也困難。后來在SQL2003標(biāo)準(zhǔn)中加入了窗口函數(shù),可以對分組編行號了,但是求各組中位數(shù)依然繁瑣。
舉個(gè)例子:現(xiàn)有成績表SCORES數(shù)據(jù)如下,要求查出每科成績的中位數(shù)。
COURSE
SCORE
History
68.5
History
79.0
History
82.5
History
88.0
History
93.5
Maths
75.5
Maths
83.0
Maths
85.0
Maths
95.5
查詢出來的各科成績中位數(shù)應(yīng)該是:
COURSE
SCORE
History
82.5
Maths
84.0
以O(shè)racle為例,用SQL寫出來是這樣:
WITH ?A ?AS
( SELECT COURSE, SCORE,
ROW_NUMBER()OVER ( PARTITION BY COURSE ORDER BY SCORE) AS RN,
COUNT(*) OVER (PARTITION BY COURSE) AS CNT
FROM SCORES ),
B ?AS
(SELECT * FROM A WHERE RN>(CNT-0.5)/2 AND RN
SELECT COURSE, AVG(SCORE) AS SCORE FROM B
GROUP BY COURSE
ORDER BY COURSE;
這里的A為每組數(shù)據(jù)加上組內(nèi)行號并統(tǒng)計(jì)每組記錄數(shù),B查出位于每組中間位置的記錄,最后從B里算出每組平均值,即為中位數(shù)。解題步驟比較多,這種SQL不好寫。另外還有不用窗口函數(shù)的辦法,語句就更加復(fù)雜了,這里不再列出。
集算器的SPL語言支持組內(nèi)運(yùn)算,也提供了中位數(shù)函數(shù),解決這個(gè)問題就會(huì)簡單很多,只需1行代碼:
connect("mydb").query("select * from scores order by course, score").group(COURSE).new(~.COURSE,~.(SCORE).median():SCORE)
SPL 擅長解決這類分組子集和組內(nèi)有序計(jì)算,請閱
、
、
集算器 SPL 是解決 SQL 難題的專業(yè)腳本語言,它語法簡單,符合自然思維,是天然分步、層次清晰的面向過程計(jì)算語言。它采用與數(shù)據(jù)庫無關(guān)的統(tǒng)一語法,編寫的算法可在數(shù)據(jù)庫間無縫遷移。它是桌面級計(jì)算工具,即裝即用,配置簡單,調(diào)試功能完善,可設(shè)置斷點(diǎn)、單步執(zhí)行,每步執(zhí)行結(jié)果都可查看。請參閱
SPL也能很方便地嵌入到JAVA應(yīng)用,可參考
。
具體使用方法可參考
。
總結(jié)
以上是生活随笔為你收集整理的oracle 计算中位数,SQL 如何计算每个分组的中位数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle pl/sql编程详解,Or
- 下一篇: oracle19c方言,JFinal框架