• 分组数据筛选(group by后取出每组的第n条数据)


        今天在一个群里有人问一个问题,如何在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.b
        FROM (SELECT a,b FROM `SAM` ORDER BY a,b) f,
        (SELECT @rank:=1,@a:=null,@b:=null) tt) t WHERE rank=3;

        
        

  • 相关阅读:
    数字签名与HTTPS详解
    利用策略模式优化过多 if else 代码
    Redis 的事务到底是不是原子性的
    Spring Boot项目的接口防刷
    深入分析 ThreadLocal
    什么是四层和七层负载均衡?他们之间的区别是什么?
    MyEclipse或Eclipse中project的导入和导出
    org.hibernate.exception.ConstraintViolationException: could not insert:
    C++ STL vector(向量容器)的使用(附完整程序代码)
    Swift2.0语言教程之函数嵌套调用形式
  • 原文地址:https://www.cnblogs.com/alala666888/p/2720980.html
Copyright © 2020-2023  润新知