来源: 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
*/
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最大的值所在行的数据。
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最小的值所在行的数据。
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分组取第一次出现的行所在的数据。
/*
name val memo
———- ———– ——————–
a 2 a2(a的第二个值)
b 1 b1–b的第一个值
*/
/*
name val memo
———- ———– ——————–
a 1 a1–a的第一个值
b 5 b5b5b5b5b5
*/
–五、按name分组取最小的两个(N个)val
select 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 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
*/
2 数据如下:
3 name val memo
4 a 2 a2(a的第二个值)
5 a 1 a1–a的第一个值
6 a 1 a1–a的第一个值
7 a 3 a3:a的第三个值
8 a 3 a3:a的第三个值
9 b 1 b1–b的第一个值
10 b 3 b3:b的第三个值
11 b 2 b2b2b2b2
12 b 4 b4b4
13 b 5 b5b5b5b5b5
14
15 */
16
附:mySQL “group by ”与”order by”的研究--分类中最新的内容
这两天让一个数据查询难了。主要是对group by 理解的不够深入。才出现这样的情况
我现在需要取出每个分类中最新的内容
结果如下
明显。这不是我想要的数据,原因是msyql已经的执行顺序是
执行顺序: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的作用是将小组里的字段里的值进行串联起来。
子查询解决方案