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

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 20:31   1428   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 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP