今天在一个群里有人问一个问题,如何在msql里执行一个查询:从一个表里面取数据,按照某个字段分组,然后取每组的第三条数据。有个人说了oracle的实现方法,用到了rank。当然,oracle我是不懂的,google的结果是mysql里面也没有rank函数。然后搜到了一篇文章研究了一下,总算折腾出来了。下面是参考文章的链接:http://blog.sina.com.cn/s/blog_4d18beb10100y3kt.html

先创建一个表作为例子:

1 CREATE TABLE sam (
2   `a` int(11) DEFAULT NULL,
3   `b` int(11) DEFAULT NULL
4 ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
5 INSERT INTO sam VALUES (1,10),(1,15),(1,20),(1,25),(2,20),(2,22),(2,33),(2,45);

表里的数据如下:
a b
1 10
1 15
1 20
1 25
2 20
2 22
2 33
2 45
    
然后就是一个查询,给每组的行都加上序号:

1 SELECT a,b,
2     @rank:=IF(@a=a, @rank+1, 1) rank,
3     @a:=a
4     FROM `sam`,
5     (SELECT @rank:=1,@a:=null) tt;

查询结果:

a b rank @a:=a
1 10 1 1
1 15 2 1
1 20 3 1
1 25 4 1
2 20 1 2
2 22 2 2
2 33 3 2
2 45 4 2

这里有些地方需要解释一下。
    第1行:这里用到了用户变量和IF函数,用户变量就是每次查询的临时变量,类似java方法里面的临时变量。IF函数类似if语句,里面有三个参数,第一个是条件,第二个是条件成功时的返回值,第三个是条件失败时的返回值。
    第3行:这里保存一下a列的值,用来跳转到下一行时在IF里面和最新a值做对比,以便决定rank是否需要重置为1。
    第5行,这里其实啥都没干,主要作用类似声明变量,反正不声明结果会很诡异,详细原因还没研究清楚。

综上所述,取每组第三行的查询语句是:

1 SELECT t.a, t.b FROM (SELECT a,b,@rank:=IF(@a=a, @rank+1, 1) rank,@a:=a FROM sam) t,
2     (SELECT @rank:=1,@a:=null) tt WHERE rank=3;

查询结果:

a b
1 20
2 33

上面没有考虑顺序,因为原始数据本来就是有顺序的。如果考虑到a、b的顺序以及b可能有重复值,可以使用下面的语句,读者可以插入几条重复数据测试一下:

SELECT t.a, t.b FROM (SELECT f.a,f.b,@rank:=IF(@b<>f.b,IF(@a=f.a, @rank+1, 1),@rank) rank,@a:=f.a,@b:=f.bFROM (SELECT a,b FROM `SAM` ORDER BY a,b) f,(SELECT @rank:=1,@a:=null,@b:=null) tt) t WHERE rank=3;

转载于:https://www.cnblogs.com/alala666888/archive/2012/10/12/2720980.html

分组数据筛选(group by后取出每组的第n条数据)相关推荐

  1. oracle分组查询取第一条数据,160804、oracle查询:取出每组中的第一条记录

    oracle查询:取出每组中的第一条记录 按type字段分组,code排序,取出每组中的第一条记录 方法一: select type,min(code) from group_info group b ...

  2. 160804、oracle查询:取出每组中的第一条记录

    oracle查询:取出每组中的第一条记录 按type字段分组,code排序,取出每组中的第一条记录 方法一: select type,min(code) from group_info  group ...

  3. oracle查询:分组查询,取出每组中的第一条记录

    按type字段分组,code排序,取出每组中的第一条记录 方法一: select type,min(code) from group_info  group by type; 注意:select 后面 ...

  4. oracle 显示最后几条,oracle 先分组后获取每组最大值的该条全部信息

    用一个实例说明: TEST表 SELECT a.* FROM ( SELECT ROW_NUMBER () OVER ( PARTITION BY MM ORDER BY DD DESC ) rn, ...

  5. Mysql分组查询每组最新的一条数据(三种实现方法)

    MySQL分组查询每组最新的一条数据 前言 注意事项 准备SQL 错误查询 错误原因 方法一 方法二(适用于自增ID和创建时间排序一致) 方法三(适用于自增ID和创建时间排序一致) 总结 MAX()函 ...

  6. SQL分组查询后取每组的前N条记录

    本文由 Leon 同学授权发布 这个公众号的关注者除了大部分是 Android 工程师之外还有部分后端以及前端同学,我鼓励也非常欢迎大家来投稿,其实我们并不需要把自己限定在某个领域,多学学其他语言也是 ...

  7. 【Mysql】Sql分组查询后取每组的前N条记录

    目录 一.背景 二.实战解析 三.总结 一.背景 最近,在开发中遇到个功能需求.系统有个资讯查询模块,要求资讯按照卡片形式展示.如下图: 按照项目组展示卡片,每个项目组展示阅读量最多的TOP2. 需求 ...

  8. mysql分组区某列最后一条_[MySQL]MySQL数据库如何按某列分组排序后查询每个分组的最后一条数据?...

    比如当前有如下的消息表(messages)及示例数据: Id Name Other_Columns ------------------------- 1 A A_data_1 2 A A_data_ ...

  9. MySQL使用group by分组查询每组最新的一笔数据

    问题来源 今天遇到一个查询数据库数据的问题:要获取每个分组最新的一笔数据,并将每个分组最新的一笔数据重新组成一个新的列表 这种场景,当然是想到了分组查询,使用 group by,思路也很清晰: 将所有 ...

  10. 160805、oracle查询:取出每组中的第一条记录

    在Java 9发布之前,我们来分享一些Java 8开发技巧 [以下为译文] 在使用JAVA 8进行开发多年后,结合个人使用IntelliJ IDEA的心得,我总结了以下几个JAVA8技巧供大家参考. ...

最新文章

  1. 完美解决方案 | 完全卸载任何版本office残余文件
  2. web.xml中如何配置Servlet文件
  3. mac osx linux,Linux 、Mac OSX 常见问题 及 笔记
  4. mysql 光标的作用_Mysql那些事儿之(十四)光标的使用_MySQL
  5. echart仪表盘旋转_使用echart仪表盘
  6. JS判断相等或者不等于(==、===、!=、!==)运算符
  7. C++的隐式转换和explicit关键字
  8. InnoDB配置文件复习
  9. 书单丨724运维日,为运维人干杯
  10. ElasticSearch8.1.2 ik分词器
  11. (二)VISIO 中间带箭头的弧线怎么画
  12. Python(爬虫篇)--- 验证码破解【二】滑块验证码
  13. 使用canvas标签绘制圆形、三角形
  14. 如何给pdf添加水印?
  15. mysql st_contains实现_查看某一个点是否在某个多边形内 使用ST_Contains函数
  16. 2021中职组网络空间安全国赛CD模块分组混战镜像*
  17. SRE(运维)最重要的是什么,看这一篇就够了
  18. 《潮流时装设计——世界顶级时装CAD制板技巧》——导读
  19. Git本地创建分支并推送到远程
  20. 3.2 daydayup举一反三:三天打鱼两天晒网式学习

热门文章

  1. 教你chrome浏览器断点调试理解闭包
  2. 去掉Eclipse插件Aptana启动显示My Aptana
  3. justify-content
  4. C++的ORM 开源框架
  5. Ubuntu系统安装VMware Tools的简单方法
  6. ARM——操作系统—最小操作系统-开发板测试
  7. 线性排序算法-堆排序 (2)
  8. 动态控制C4C UI元素的显示和隐藏
  9. Handler深入(分析源码,手写一套Handler)
  10. COGS 265 线段覆盖