zoukankan      html  css  js  c++  java
  • mysql单列去重复group by分组取每组前几条记录加order by排序

    mysql分组取每组前几条记录(排名) 附group by与order by的研究,需要的朋友可以参考下

    --按某一字段分组取最大(小)值所在行的数据 

    复制代码代码如下:


    /* 
    数据如下: 
    name val memo 
    a 2 a2(a的第二个值) 
    a 1 a1--a的第一个值 
    a 3 a3:a的第三个值 
    b 1 b1--b的第一个值 
    b 3 b3:b的第三个值 
    b 2 b2b2b2b2 
    b 4 b4b4 
    b 5 b5b5b5b5b5 
    */ 


    --创建表并插入数据: 

    复制代码代码如下:


    create table tb(name varchar(10),val int,memo varchar(20)) 
    insert into tb values('a', 2, 'a2(a的第二个值)') 
    insert into tb values('a', 1, 'a1--a的第一个值') 
    insert into tb values('a', 3, 'a3:a的第三个值') 
    insert into tb values('b', 1, 'b1--b的第一个值') 
    insert into tb values('b', 3, 'b3:b的第三个值') 
    insert into tb values('b', 2, 'b2b2b2b2') 
    insert into tb values('b', 4, 'b4b4') 
    insert into tb values('b', 5, 'b5b5b5b5b5') 
    go 


    --一、按name分组取val最大的值所在行的数据。 

    复制代码代码如下:


    --方法1:select a.* from tb a where val = (select max(val) from tb where name = a.name) order by a.name 
    --方法2: 
    select a.* from tb a where not exists(select 1 from tb where name = a.name and val > a.val) 
    --方法3: 
    select a.* from tb a,(select name,max(val) val from tb group by name) b where a.name = b.name and a.val = b.val order by a.name 
    --方法4: 
    select a.* from tb a inner join (select name , max(val) val from tb group by name) b on a.name = b.name and a.val = b.val order by a.name 
    --方法5 
    select a.* from tb a where 1 > (select count(*) from tb where name = a.name and val > a.val ) order by a.name 
    /* 
    name val memo 
    ---------- ----------- -------------------- 
    a 3 a3:a的第三个值 
    b 5 b5b5b5b5b5 
    */ 


    本人推荐使用1,3,4,结果显示1,3,4效率相同,2,5效率差些,不过我3,4效率相同毫无疑问,1就不一样了,想不搞了。 
    --二、按name分组取val最小的值所在行的数据。 

    复制代码代码如下:


    --方法1:select a.* from tb a where val = (select min(val) from tb where name = a.name) order by a.name 
    --方法2: 
    select a.* from tb a where not exists(select 1 from tb where name = a.name and val < a.val) 
    --方法3: 
    select a.* from tb a,(select name,min(val) val from tb group by name) b where a.name = b.name and a.val = b.val order by a.name 
    --方法4: 
    select a.* from tb a inner join (select name , min(val) val from tb group by name) b on a.name = b.name and a.val = b.val order by a.name 
    --方法5 
    select a.* from tb a where 1 > (select count(*) from tb where name = a.name and val < a.val) order by a.name 
    /* 
    name val memo 
    ---------- ----------- -------------------- 
    a 1 a1--a的第一个值 
    b 1 b1--b的第一个值 
    */ 


    --三、按name分组取第一次出现的行所在的数据。 

    复制代码代码如下:


    select a.* from tb a where val = (select top 1 val from tb where name = a.name) order by a.name 
    /* 
    name val memo 
    ---------- ----------- -------------------- 
    a 2 a2(a的第二个值) 
    b 1 b1--b的第一个值 
    */ 


    --四、按name分组随机取一条数据。 

    复制代码代码如下:


    select a.* from tb a where val = (select top 1 val from tb where name = a.name order by newid()) order by a.name/* 
    name val memo 
    ---------- ----------- -------------------- 
    a 1 a1--a的第一个值 
    b 5 b5b5b5b5b5 
    */ 


    --五、按name分组取最小的两个(N个)val 

    复制代码代码如下:


    select a.* from tb a where 2 > (select count(*) from tb where name = a.name and val < a.val ) order by a.name,a.valselect a.* from tb a where val in (select top 2 val from tb where name=a.name order by val) order by a.name,a.val 
    select a.* from tb a where exists (select count(*) from tb where name = a.name and val < a.val having Count(*) < 2) order by a.name 
    /* 
    name val memo 
    ---------- ----------- -------------------- 
    a 1 a1--a的第一个值 
    a 2 a2(a的第二个值) 
    b 1 b1--b的第一个值 
    b 2 b2b2b2b2 
    */ 


    --六、按name分组取最大的两个(N个)val 

    复制代码代码如下:


    select a.* from tb a where 2 > (select count(*) from tb where name = a.name and val > a.val ) order by a.name,a.val 
    select a.* from tb a where val in (select top 2 val from tb where name=a.name order by val desc) order by a.name,a.val 
    select a.* from tb a where exists (select count(*) from tb where name = a.name and val > a.val having Count(*) < 2) order by a.name 
    /* 
    name val memo 
    ---------- ----------- -------------------- 
    a 2 a2(a的第二个值) 
    a 3 a3:a的第三个值 
    b 4 b4b4 
    b 5 b5b5b5b5b5 
    */ 


    --七,假如整行数据有重复,所有的列都相同(例如下表中的第5,6两行数据完全相同)。 
    按name分组取最大的两个(N个)val 

    复制代码代码如下:


    /* 
    数据如下: 
    name val memo 
    a 2 a2(a的第二个值) 
    a 1 a1--a的第一个值 
    a 1 a1--a的第一个值 
    a 3 a3:a的第三个值 
    a 3 a3:a的第三个值 
    b 1 b1--b的第一个值 
    b 3 b3:b的第三个值 
    b 2 b2b2b2b2 
    b 4 b4b4 
    b 5 b5b5b5b5b5 
    */ 


    附:mysql “group by ”与"order by"的研究

     这两天让一个数据查询难了。主要是对group by 理解的不够深入。才出现这样的情况

    这种需求,我想很多人都遇到过。下面是我模拟我的内容表

    我现在需要取出每个分类中最新的内容

    select * from test group by category_id order by `date`


    结果如下

    明显。这不是我想要的数据,原因是msyql已经的执行顺序是

    引用


    写的顺序:select ... from... where.... group by... having... order by..
    执行顺序:from... where...group by... having.... select ... order by...


    所以在order by拿到的结果里已经是分组的完的最后结果。
    由from到where的结果如下的内容。

    到group by时就得到了根据category_id分出来的多个小组

    到了select的时候,只从上面的每个组里取第一条信息结果会如下

    即使order by也只是从上面的结果里进行排序。并不是每个分类的最新信息。
    回到我的目的上 --分类中最新的信息
    根据上面的分析,group by到select时只取到分组里的第一条信息。有两个解决方法
    1,where+group by(对小组进行排序)
    2,从form返回的数据下手脚(即用子查询)
    由where+group by的解决方法
    对group by里的小组进行排序的函数我只查到group_concat()可以进行排序,但group_concat的作用是将小组里的字段里的值进行串联起来。

    select group_concat(id order by `date` desc) from `test` group by category_id

    再改进一下

    select * from `test` where id in(select SUBSTRING_INDEX(group_concat(id order by `date` desc),',',1) from `test` group by category_id ) order by `date` desc

    子查询解决方案

    select * from (select * from `test` order by `date` desc) `temp`  group by category_id order by `date` desc

     

  • 相关阅读:
    2021NUAA暑假集训 Day3 题解
    2021NUAA暑假集训 Day2 题解
    2021NUAA暑期模拟赛部分题解
    CodeForces 1038D Slime
    UVA 11149 Power of Matrix
    UVA 10655 Contemplation! Algebra
    UVA 10689 Yet another Number Sequence
    HDU 4549 M斐波那契数列
    HDU 4990 Reading comprehension
    CodeForces 450B Jzzhu and Sequences
  • 原文地址:https://www.cnblogs.com/mengdejun/p/mysql_group_order_by.html
Copyright © 2011-2022 走看看