日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql count 排序_SQL进阶排序和窗口函数

發布時間:2024/4/13 数据库 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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個函數的區別通過一個列子可以清楚地看到:

select
name,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()函數的排名
價格排名+1
10001
8012
5023

「如果希望排序從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进阶排序和窗口函数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。