mysql count 排序_SQL进阶排序和窗口函数
生活随笔
收集整理的這篇文章主要介紹了
mysql count 排序_SQL进阶排序和窗口函数
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在使用數據庫制作各種統計數據的時候,需要對數據進行排序,比如按照「分數、銷量、人數」等數值進行排序,通常排序的方法有兩種:
- 跳過之后的位次排序
- 不跳過之后的位次排序
窗口函數
窗口函數只在最新的MySQL版本中才支持的!
窗口函數只在最新的MySQL版本中才支持的!
窗口函數只在最新的MySQL版本中才支持的!
參考資料:https://zhuanlan.zhihu.com/p/92654574
什么是窗口函數
窗口函數,也叫OLAP函數(Online Anallytical Processing,聯機分析處理),可以對數據庫數據進行實時分析處理。
語法
窗口函數的基本語法:
over (partition by -- partition子句可省略,不指定分組order by )
的位置上可以放兩種函數:
- 專用窗口函數,rank、dense_rank、row_number等
- 聚合函數,如sum、avg、count、max、min等
因為窗口函數是對where或者group by子句處理后的結果進行操作,所以「窗口函數原則上只能寫在select子句中」。
功能
- 同時具有分組和排序的功能
- 不改變原有表的行數
- 窗口函數原則上只能寫在select子句中
實際場景
- 排名問題:每個部門按業績來排名
- topN問題:找出每個部門排名前N的員工進行獎勵
rank/dense_rank/row_number
實例
- rank:并列跳躍排名
- dense_rank:并列連續排名
- row_number:連續排名
這3個函數的區別通過一個列子可以清楚地看到:
selectname,price,
rank() over (order by price desc) as rank_1,
dense_rank() (order by price desc) as rank_2,
row_number() (order by price desc) as rank_3
from products;
結論
name price rank_1 rank_2 rank_3橘子 100 1 1 1
西瓜 80 2 2 2
蘋果 50 3 3 3
香蕉 50 3 3 4
葡萄 50 3 3 5
檸檬 30 6 4 6
總結:
- rank()在出現了相同位次之后,跳過了相同的位次
- dense_rank()則沒有跳過相同的位次
- row_number()按照自然數的順序進行排列
在上述的這三個專用窗口函數中,函數后面的括號不需要任何參數,保持()空著就可以。
?知乎例子
實現rank()
select *,rank() over (partition by 班級 -- 先分組
order by 成績 desc) as ranking -- 再排序
from 班級表
不改變行數
非等值連接實現rank()
select p1.name,p1.price,(select count(p2.price)
from products p2
where p2.price > p1.price) + 1
as rank_1
from products
order by rank_1;
- 子查詢的功能是計算出比自己(p1)高的記錄,并將其作為自己的位次
- 比如對去重之后的價格{100,80,50}進行分析和排序,比100大的個數是0,比80大的個數是1,比50大的個數是2
- +1之后的排名實際上就是下面將會提到的dense_rank()函數的排名
| 100 | 0 | 1 |
| 80 | 1 | 2 |
| 50 | 2 | 3 |
「如果希望排序從0開始,則去掉加1」:
非等值連接實現dense_rank()
mysql> select p1.name, p1.price,(select count(distinct p2.price) from products p2 where p2.price > p1.price) + 1 as rank_1
from products p1
order by rank_1;
使用變量實現row_number()
在MySQL5.7.28中實現變量實現row_number函數的功能
mysql> select p.name, p.price, (@pro_rank := @pro_rank + 1) row_Number-> from products p,(select @pro_rank := 0) r
-> order by price desc;
如果是更高級的MySQL版本,直接使用row_number()函數實現
select name, price,row_number() over (partition by name order by price desc) as rowNumber
from products
聚合函數作為窗口函數
聚合窗口函數和上面提到的專用窗口函數用法完全相同,只需要把「聚合函數」寫在窗口函數的位置即可
- 「函數后面括號里面不能為空」
- 需要指定聚合的列名
需要在高級的MySQL版本或者hive中實現
mysql> select *,-> sum(price) over (order by name) as rank_sum,
-> avg(price) over (order by name) as rank_avg,
-> max(price) over (order by name) as rank_max,
-> count(price) over (order by name) as rank_count
-> from products;
總結
以上是生活随笔為你收集整理的mysql count 排序_SQL进阶排序和窗口函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python中如何删除字典中的元素_py
- 下一篇: 边缘计算架构_更灵活的自动化系统架构、通