server sql 众数_sql 语句系列(众数中位数与百分比)[八百章之第十五章]
眾數(shù)
眾數(shù)就是出現(xiàn)最多的那個數(shù)。
select sal,count(*) as cnt
from emp
where DEPTNO=20
group by sal
通過分組把他們的行數(shù)計算出來。那么最關(guān)鍵的部分在于,你如何知道最大值。
是的我們可以查出當(dāng)前最大值,然后再取出最大值的sal。但是這肯定要用到兩個臨時視圖。
注:我們不能通過排序cnt,然后取值第一個,因為可能存在相同的行數(shù)。
解決方案:通過dense_rank 進(jìn)行排序。
科普一下概念:
row_number的用途非常廣泛,排序最好用它,它會為查詢出來的每一行記錄生成一個序號,依次排序且不會重復(fù),注意使用row_number函數(shù)時必須要用over子句選擇對某一列進(jìn)行排序才能生成序號。
rank函數(shù)用于返回結(jié)果集的分區(qū)內(nèi)每行的排名,行的排名是相關(guān)行之前的排名數(shù)加一。簡單來說rank函數(shù)就是對查詢出來的記錄進(jìn)行排名,與row_number函數(shù)不同的是,rank函數(shù)考慮到了over子句中排序字段值相同的情況,如果使用rank函數(shù)來生成序號,over子句中排序字段值相同的序號是一樣的,后面字段值不相同的序號將跳過相同的排名號排下一個,也就是相關(guān)行之前的排名數(shù)加一,可以理解為根據(jù)當(dāng)前的記錄數(shù)生成序號,后面的記錄依此類推。
dense_rank函數(shù)的功能與rank函數(shù)類似,dense_rank函數(shù)在生成序號時是連續(xù)的,而rank函數(shù)生成的序號有可能不連續(xù)。dense_rank函數(shù)出現(xiàn)相同排名時,將不跳過相同排名號,rank值緊接上一次的rank值。在各個分組內(nèi),rank()是跳躍排序,有兩個第一名時接下來就是第三名,dense_rank()是連續(xù)排序,有兩個第一名時仍然跟著第二名。
答案:
sql server
select sal
from(
select sal,DENSE_RANK() over(order by cnt desc) as rnk
from (select sal,count(*) as cnt
from emp
where DEPTNO=20
group by sal
) x) y
where rnk=1
mysql
select sal,count(*) as cnt
from EMP
where DEPTNO=20
group by sal
HAVING COUNT(*)>=all(
select count(*)
from EMP
where DEPTNO=20
group by sal
)
因為mysql 沒有DENSE_RANK,所以只能通過大于等于所有值來完成。這樣就相當(dāng)于查詢了兩遍。
中位數(shù)
這個比較簡單:
sql service
select avg(SAL) as sal from
(select SAL,COUNT(*) over() total,CAST(COUNT(*) over() as decimal)/2 mid,CEILING((CAST(COUNT(*) over() as decimal)/2)) as next,
ROW_NUMBER() over(order by sal) rn
from emp
where DEPTNO=20) x
where (total%2=0 and rn in(mid,mid+1))
or (total%2=1 and rn=next)
可能看起來比較復(fù)雜,拆開來一下:
select SAL,COUNT(*) over() total,CAST(COUNT(*) over() as decimal)/2 mid,CEILING((CAST(COUNT(*) over() as decimal)/2)) as next,
ROW_NUMBER() over(order by sal) rn
from emp
where DEPTNO=20
這樣就很清晰了。
mysql:
select avg(x.sal)
FROM(
select e.sal
from EMP e,EMP d
where e.deptno=d.deptno
and e.deptno=20
GROUP BY e.SAL
HAVING SUM(case when e.sal=d.sal then 1 else 0 end)>=abs(sum(sign(e.sal-d.SAL)))) x
一開始我也很懵逼,后來這樣:
select e.sal,SUM(case when e.sal=d.sal then 1 else 0 end),abs(sum(sign(e.sal-d.SAL)))
from EMP e,EMP d
where e.deptno=d.deptno
and e.deptno=20
GROUP BY e.SAL
如果自己相同的數(shù)大于等于它左右兩邊差距數(shù),那么其是中位數(shù)。
百分比
其他沒什么值得注意的,就是算除法。
唯一值得關(guān)注的是:
如果是int類型,那么應(yīng)該轉(zhuǎn)換,再去計算。
CAST(x.d10 as decimal)
總結(jié)
以上是生活随笔為你收集整理的server sql 众数_sql 语句系列(众数中位数与百分比)[八百章之第十五章]的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 现代软件工程 第三章 【软件工程师的成长
- 下一篇: 新手一小时就写出人工智能应用 - 看图识