如何在交易數據中查詢各個版本交易量前三的股票?(MySQL分組排名)

SQL查詢中,根據列A分組,分組後針對列B執行統計函數,是一件常用也很重要功能,如
select T.a, max(T.b) from T order by T.a asc, T.b desc group by T.a
select T.a, count(T.b) from T order by T.a asc, T.b desc group by T.a
一直這樣寫SQL,直到有一天,一個做股票的朋友(非IT人事)和我聊天,說他自己用Python整了點數據,想分析下每個版塊成交量前三的股票,問我知不知道怎麼用SQL查出來(這是一個分組排名取若干首級的需求)。老實說,這個問題很常見,但是腦子剎那間有點懵逼,回來的路上一直想這個問題,若干年前用SQLServer時,有個分組方法ROW_NUMBER() OVER(),貌似可以實現這個分組排名功能。

語法格式:row_number() over(partition by 分組列 order by 排序列 desc)

與是網上搜了下MySQL 的實現,果然一堆朋友記錄過。參照了一篇CSDN微博“Mysql實現ROW_NUMBER() OVER()” 的內容,將實現過程記錄如下。

先看下錶結構:
view_market_trade_amt有三列,第一列是指數,第二列是股票代碼,第三列是成交量。
需求是將各個指數板塊的成交前三的股票查出來。
如何在交易數據中查詢各個版本交易量前三的股票?(MySQL分組排名)

實現MySQL rownum() over()之前,需要先了解下這種實現方式的思想:根據分組列排序後,定義rownum標記,rownum的標記隨着分組列變化而變化,分組列值相同時,rownum不變,最後每個分組列形成一個rownum序列,之後根據rownum序列篩選排名。

  1. 定義rownum
select  v.stockCode,v.tradeIndex,v.amount,
if(@grpvar=v.tradeIndex,@rownum:=@rownum+1,@rownum:=1) as rownum, @grpvar:=v.tradeIndex
from (select stockCode,tradeIndex,amount from view_market_trade_amt order by tradeIndex asc ,amount desc) v ,
(select @grpvar := null ,@rownum:=0)  vardef

vardef是定義分組變量和rownum變量,分別默認賦值null和0;
grpvar賦值tradexIndex,同時判斷當前記錄的tradeIndex和該變量是否相等,如果相等則rownum+1,否則從1開始賦值。
查詢結果:
如何在交易數據中查詢各個版本交易量前三的股票?(MySQL分組排名)

如何在交易數據中查詢各個版本交易量前三的股票?(MySQL分組排名)

可以看到,不同的tradeIndex,對應rownum序列都是獨立。

  1. 根據rownum篩選記錄
    這一步就簡單的多了,基於上面的繼續,篩選出rownum小於3的即可。
select tradeIndex, stockCode, amount from (

select  v.stockCode,v.tradeIndex,v.amount,
if(@grpvar=v.tradeIndex,@rownum:=@rownum+1,@rownum:=1) as rownum, @grpvar:=v.tradeIndex
from (select stockCode,tradeIndex,amount from view_market_trade_amt order by tradeIndex asc ,amount desc) v ,
(select @grpvar := null ,@rownum:=0)  vardef

)  as result
where result.rownum<=3

如何在交易數據中查詢各個版本交易量前三的股票?(MySQL分組排名)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章