Mysql5.7版本實現row_number窗口函數的分組排序功能

我在這篇博客https://www.cnblogs.com/chendongblog/p/11887712.html中說過,html

在 sql server中outer apply / cross apply 能夠更高效率的實現跟row_number函數同等的功能mysql

但mysql 5.7 不只outer apply / across apply 沒有, row_number也沒有. 哭 !sql

據說mysql 8.0 版本 也可使用row_number函數了app

但咱們使用的是5.7版本函數

網上的資料不少, 但感受不夠簡潔明瞭, 我就本身寫一下好了url

SELECT * FROM ( SELECT 
@rn:= CASE WHEN @securityid = securityid THEN @rn + 1 ELSE 1 END AS rn, @securityid:= securityid as securityid, volume, date FROM (SELECT * from us_historicaldaily WHERE DATE <= '2019-05-16' ORDER BY securityid, date DESC) a ,(SELECT @rn=0, @securityid=0) b )a WHERE rn <= 5

這裏有幾點解釋下:spa

1. 這裏對錶分組的依據是securityid, 排序的依據是date.net

至關於有個指針在從上往下滑動,  須要一個用戶變量@securityid來記錄最近一次securityid的值, 指針

而後跟當前行的securityid列作對比, 若是相等(@securityid = securityid) 說明當前在同一個分組中, @rn 遞增1 ,code

不然說明當前組已經變動了 @rn從新計數, 從1開始

2. a表中order by 是必須的,  由於只有排序的表從上往下遍歷纔有意義,

並且order by的字段順序要至關於row_number函數的 partition by securityid order by date desc

因爲sql的執行順序, order by 排在select 以後, 因此order by語句必須寫在a表中, 而不是整個sql的末尾(剛好mysql支持order by語句寫在表中)

3. b表也是必須的, b表至關於在a表後面加兩個字段初始化這兩個變量的值, 也能夠用set關鍵字初始化, 但我仍是喜歡用表.

結果以下

相關文章
相關標籤/搜索