mysql top 1_实现 MySQL Top 函数【原创】

逃离我推掉我的手 2023-01-12 07:59 210阅读 0赞

需求:查询数据,根据字段分组,取出分组后每组的前N条记录。

如果是在SQL Server中,可以使用top,取前N条记录。但是在MySQL是不支持的。网上说的比较多的是用limit N,虽然可以取到前N条,但那是分组后的N条,不是每组N条数据,所以不符合需求,排除。还有一种是使用union把多个结果连接起来,这种方法需要提前知道有分多少组,而且不适合分组太多的场景,排除。

我的实现思路:

1.查出分组后的数据。

2.使用原表数据和分组后的数据连接起来。

3.按组生成序列(从0开始)。

4.根据序列编号做为条件,找出前N条数据。

SQL如下:

按月分组

SELECT

tid, endDate

FROM

reportform.reportform_user_active AS rua

GROUP BY DATE_FORMAT(endDate, ‘%y-%m’);

执行结果:

2cb8ef416ea46b607bb74f4f66e6e1c4.png

给分组后的数据加上序列,rowNum(从0开始)。

SELECT

rua.tid,

rua.endDate,

(@i:=IF(tmp.tid IS NULL, @i + 1, @i:=0)) AS rowNum

FROM

reportform.reportform_user_active AS rua

LEFT JOIN (SELECT

tid, endDate

FROM

reportform.reportform_user_active

GROUP BY DATE_FORMAT(endDate, ‘%y-%m’)) AS tmp ON tmp.tid = rua.tid, (SELECT @i:=0) AS i

执行结果:

7c91f5197867ad02134bc9335f27f682.png

9df586492f73dc19eb42573bfaa9e5b3.png

de560c1838ac92dd3df9dcd1f184d04f.png

可以看到,每月开始生成序号,从0开始。

最终SQL,取出前3条记录:

SELECT

*

FROM

(SELECT

rua.tid,

rua.endDate,

(@i:=IF(tmp.tid IS NULL, @i + 1, @i:=0)) AS rowNum

FROM

reportform.reportform_user_active AS rua

LEFT JOIN (SELECT

tid, endDate

FROM

reportform.reportform_user_active

GROUP BY DATE_FORMAT(endDate, ‘%y-%m’)) AS tmp ON tmp.tid = rua.tid, (SELECT @i:=0) AS i) AS t

WHERE

t.rowNum < 3;

执行结果:

0258495698114b38ff3ff976afa185a8.png

提示:如果数据库是Oracle或SQL Server,可以用ROW_NUMBER函数生成序列。

发表评论

表情:
评论列表 (有 0 条评论,210人围观)

还没有评论,来说两句吧...

相关阅读

    相关 TOP

    系统运行时间和平均负载: top命令的顶部显示与uptime命令相似的输出。 这些字段显示: 当前时间系统已运行的时间 当前登录用户的数量 相应