`
MauerSu
  • 浏览: 513577 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

mysql查询 分组后前 N条数据

 
阅读更多
源:http://www.jb51.net/article/31590.htm
评:
msql in的子查询内无法用limit
mysql分组 取前N条数据 语句
select a.* from tb a where N > (select count(*) from tb where name = a.name and val > a.val ) order by a.name,a.val


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',    1,   'a1--a的第一个值')
insert into tb values('a',    3,   'a3: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')
mysql分组 取前2条数据 语句
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


--按某一字段分组取最大(小)值所在行的数据
复制代码 代码如下:

/*
数据如下:
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




分享到:
评论

相关推荐

    mysql使用GROUP BY分组实现取前N条记录的方法

    mysql分组,取记录 GROUP BY之后如何取每组的前两位下面我来讲述mysql中GROUP BY分组取前N条记录实现方法。 这是测试表(也不知道怎么想的,当时表名直接敲了个aa,汗~~~~): 结果: 方法一: 代码如下:SELECT a....

    mysql分组取每组前几条记录(排名) 附group by与order by的研究

    –按某一字段分组取最大(小)值所在行的数据 代码如下: /* 数据如下: nameval 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 ...

    MySql实现分组取n条最大记录.txt

    本篇文章详细介绍了如何使用MySQL实现分组取n条最大记录的功能。通过精心设计的SQL查询语句,我们可以有效地解决这类问题。这种方法不仅适用于上述具体场景,还可以扩展应用于其他类似的需求,例如按不同标准分组并...

    MySQL获取所有分类的前N条记录

    在MySQL数据库中,获取每个分类的前N条记录是一个常见的查询需求,特别是在处理如文章、商品、用户等分组信息时。以下将详细介绍如何通过SQL语句实现这一功能,并给出三个示例。 首先,我们需要理解基本的SQL语法,...

    如何统计MySQL数据量大小

    本文将详细讲解如何统计MySQL数据库的数据量大小,并涉及CONCAT函数的解读,以及对information_schema和performance_schema库的查询方法。 首先,我们需要理解数据量统计的基本概念。数据量通常指的是数据库中所有...

    详解MySQL分组排序求Top N

    MySQL分组排序求Top N是数据库查询中一种常见的需求,特别是在数据分析、报表生成或数据挖掘等场景中。本文将深入探讨这一主题,帮助你理解如何在MySQL中有效地实现这一功能。 首先,我们要明白分组(GROUP BY)和...

    分组并排序取前N

    标题“分组并排序取前N”涉及到数据库查询中的一个重要概念,这通常指的是在SQL查询中使用`GROUP BY`、`ORDER BY`以及`LIMIT`子句来对数据进行分组、排序,并提取出每组中排名靠前的N条记录。在数据库管理中,这种...

    MySql基本查询、连接查询、子查询、正则表达查询讲解

    查询数据是指从数据库中的数据表或视图中获取所需要的数据,在mysql中,可以使用SELECT语句来查询数据。根据查询条件的不同,数据库系统会找到不同的数据。 SELECT语句的基本语法格式如下: [sql] view plain copy ...

    MySQL数据库:项目查询与维护学生信息管理数据表.pptx

    MySQL 数据库:项目查询与维护学生信息管理数据表 MySQL 数据库是当前最流行的关系型数据库管理系统之一,广泛应用于各种企业及个人项目中。为帮助读者更好地掌握 MySQL 数据库的查询与维护技术,本资源将详细介绍...

    mysql获取group by总记录行数的方法

    这样,第一个查询将返回分组后的数据,第二个查询则给出所有数据的总数,包括分组前的原始记录数。 在实际应用中,如果你的查询涉及到多表连接和`GROUP BY`操作,可以像下面这样使用: ```sql SELECT SQL_CALC_...

    mysql代码-查询每天前三条数据 按照交易价格大到小排序 相当于模拟Oracle Row_Number() OVER (partition by date ORDER BY pay desc)

    在MySQL中,我们经常需要对数据进行分组并按特定条件进行排序,特别是在处理时间序列数据时,例如查询每天的前N条记录。这个场景在Oracle数据库中可以通过使用`ROW_NUMBER()`窗口函数来实现,但在MySQL中,由于不...

    sql基本语句30条

    **解释**:这些语句分别用于在Access、SQL Server和MySQL中随机选取前n条记录。 ### 8. 查询超过五分钟未完成的任务 **语法示例**: ```sql SELECT * FROM &lt;table_name&gt; WHERE DATEDIFF(MINUTE, start_time, ...

    MySQL查询指令汇总

    - **查询第 3 页的数据,每页显示 5 条记录**: ```sql SELECT * FROM staffs LIMIT 5 OFFSET 10; ``` - **公式计算偏移量**: ```sql offset = (page - 1) * num; ``` ##### 6. 子查询 - **基本语法**: ...

    快速消费品数据分析mysql测试题-mysql.docx.pdf

    10. 提取前N条记录:在MySQL中,可以使用`LIMIT`语句来获取表的前N条记录,如`SELECT * FROM TABLE LIMIT 5`。 **填空题答案** 1. DML(Data Manipulation Language)是数据操作语言的英文缩写。 2. DDL(Data ...

    mysql查询语句汇总.rar

    - **HAVING**:在分组后筛选,`SELECT column1, COUNT(*) FROM table GROUP BY column1 HAVING COUNT(*) &gt; N;` 6. **视图** - **CREATE VIEW**:创建虚拟表,方便重复查询,`CREATE VIEW view_name AS SELECT ...

    mysql 入门笔记 简单易学。一小时上手

    例如“LIMIT(n-1)*count, count”,其中(n-1)*count计算起始位置,count表示每页显示的条数,这种写法可以实现数据的分页查询。 3. 别名:在SQL查询中使用别名可以简化SQL语句的复杂性,并使得输出结果的列名更加...

    mysql代码-MySQL-查询成绩为第二名(第N名)的所有学生数据

    标题提到的是如何查询成绩为第二名,也就是第N名(在这个例子中N等于2)的所有学生数据。这涉及到SQL语句中的聚合函数、排序以及可能的分组操作。下面将详细解释如何实现这个查询。 首先,假设我们有一个名为`...

Global site tag (gtag.js) - Google Analytics