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关键字初始化, 但我仍是喜欢用表.

结果以下

相关文章
相关标签/搜索