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