类如 有一个帖子的回复表,posts( id , tid , subject , message , dateline ) ,
id 为 自动增长字段, tid为该回复的主题帖子的id(外键关联), subject 为回复标题, message 为回复内容, dateline 为回复时间,用UNIX 时间戳表示,
现在要求 选出 前十个来自不同主题的最新回复
SELECT * FROM posts GROUP BY tid LIMIT 10
这样一个sql语句选出来的并非你想要的 最新的回复,而是最早的回复,实际上是某篇主题的第一条回复记录!
也就是说 GROUP BY 语句没有排序,那么怎么才能让 GROUP 按照 dateline 倒序排列呢?加上 order by 子句?
看下面:
SELECT * FROM posts GROUP BY tid ORDER BY dateline DESC LIMIT 10
这条语句选出来的结果和上面的完全一样,不过把结果倒序排列 了,而选择出来的每一条记录仍然是上面的记录,原因是 group by 会比 order by 先执行,这样也就没有办法将 group by 之前,也就是在分组之前进行排序了, 有网友会写出下面的sql 语句:
SELECT * FROM posts GROUP BY tid DESC ORDER BY dateline DESC LIMIT 10
也就是说 在 GROUP BY 的字段 tid 后面加上递减顺序,这样不就可以取得分组时的最后回复了吗?这个语句执行结果会和上面的一模一样,这里加上 DESC 和ASC对执行结果没有任何影响!其实这是一个错误的语句,原因是GROUP BY 之前并没有排序功能,mysql 手册上面说,GROUP BY 时是按照某种顺序排序的,某种顺序到底是什么顺序?其实根本没有顺序,因为按照tid分组,其实也就是说,把tid相等的归纳到一个组,这样想的话,GROUP BY tid DESC 可以认为是在按照 tid 分组的时候,按照tid进行倒序排列,这不扯吗,既然是按照tid分组,当然是tid相等的归到一组,而这时候按照tid倒叙还是升序有个P用!
于 是有网友发明下面的语句:
SELECT * FROM posts GROUP BY tid , dateline DESC ORDER BY dateline DESC LIMIT 10
心 想这样我就可以在分组前按照 dateline 倒序排列了,其实这个语句并没有起到按照tid分组的作用,原因还是上面的,在group by 字段后加 desc 还是 asc 是错误的写法,而这种写法 网友本意是想 按照 tid 分组,并且在分组的时候按照 dateline排倒序!而实际这句相当于下面的写法:(去掉 GROUP BY 字段后面的 DESC)
SELECT * FROM posts GROUP BY tid , dateline ORDER BY dateline DESC LIMIT 10
也就是说,按照 tid 和 dateline 联合分组,只有在记录tid和dateline 同时相等的时候才归纳到一组,这显然不可能,因为 dateline 时间线基本上是唯一的!
有人写出下面的语句:
SELECT *,max(dateline) as max_line FROM posts GROUP BY tid ORDER BY dateline DESC LIMIT 10
这条语句的没错是选出了最大发布时间,但是你可 以对比一下 dateline 和 max_dateline 并不相等!(可能有相当的情况,就是分组的目标记录只有一条的时候!)
为 什么呢?原因很简单,这条语句相当于是 在group by 以后选出本组的最大的发布时间!对分组没有起到任何影响!因为SELECT子句是最后执行的!
后来更有网友发明了下面的写法!
SELECT *,max(dateline) as max_line FROM posts GROUP BY tid HAVING dateline=max(dateline)
ORDER BY dateline DESC LIMIT 10
这条语句的预期结果和想象中的并不相同!因为你会发现,分组的结果 中大量的记录没有了!为什么?因为 HAVING 是在分组的时候执行的,也就说:在分组的时候加上一个这样的条件:选择出来的 dateline 要和 本组最大的dateline 相等,执行的结果和下面的语句相同:
SELECT *,max(dateline) as max_line FROM posts GROUP BY tid HAVING count(*)=1
ORDER BY dateline DESC LIMIT 10
看 了这条sql语句是不是明白了呢?
dateline=max(dateline) 只有在分组中的记录只有一条的时候才成立,原因很明白吧!只有一条他才会和本组的最大发布时间相等阿,(默认dateline为不重复的值)
原 因还是因为 group by 并没有排序功能,所有的这些排序功能只是错觉,所以你最终选出的 dateline 和max(dateline) 永远不可能相等,除非本组的记录只有一条!GROUP BY 在分组的时候,可能是一个一个来找的,发现有相等的tid,去掉,保留第一个发现的那一条记录,所以找出来的记录永远只是按照默认索引顺序排列的!
那 么说了这么多,到底有没有办法让 group by 执行前分组阿?有的 ,子查询阿!
最简单的 :
SELECT * FROM (SELECT * FROM posts ORDER BY dateline DESC) GROUP BY tid ORDER BY dateline DESC LIMIT 10
也 有网友利用自连接实现的 ,这样的效率应该比上面的子查询效率高,不过,为了简单明了,就只用这样一种了,GROUP BY没有排序功能,可能是mysql弱智的地方,也许是我还没有发现,
期待高人拍砖!
以上转之:http://www.alixixi.com/program/a/2011012867346.shtml
我在按照作者的思路下解决了该麻烦,非常感谢作者啊!不过还有一点要注意,
SELECT * FROM (SELECT * FROM posts ORDER BY dateline DESC) 在这段代码后要为该查询语句起个别名,作表名使用,不然报错!
完全正确的写法:
SELECT * FROM (SELECT * FROM posts ORDER BY dateline DESC) BIAOMING GROUP BY tid ORDER BY dateline DESC LIMIT 10
相关推荐
–按某一字段分组取最大(小)值所在行的数据 代码如下: /* 数据如下: 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 ...
因此,对于获取分组后每组的最大值,正确的方法是使用`INNER JOIN`结合`GROUP BY`和`MAX`函数。这不仅能确保每个分组只返回一条记录,而且返回的是该分组内分数最高的记录。在实际应用中,要根据数据库的特性和需求...
在SQL中,分组查询是通过`GROUP BY`子句来实现的,它可以将数据按照一个或多个列的值进行分组,通常结合聚合函数一起使用,以便对每个分组执行计算。 1. SQL中的分组查询 在SQL中,使用`GROUP BY`语句进行分组操作...
- `MAX()`: 找到分组内数值列的最大值。 - `MIN()`: 找到分组内数值列的最小值。 - `GROUP_CONCAT()`: MySQL特有的函数,用于将分组内的字符串连接成一个字符串。 3. **多列分组**: - 可以同时对多个列进行...
在MySQL数据库中,当执行`GROUP BY`语句时,通常是为了对数据进行分组并进行聚合计算,如计算每个组的总数、平均值等。然而,标准的`GROUP BY`查询并不直接提供每个组的行数,而是返回每个组的一行数据。如果需要...
MySQL中的`GROUP BY`语句是用于对数据库中的数据进行分组,以便可以对每个分组执行聚合操作,如计算总和、平均值、最大值、最小值等。这个功能在数据分析和报表生成中非常常见,因为它允许我们按特定字段对数据进行...
##### 示例4:按列进行分组,并计算每个分组中的最大值 ```sql SELECT column_name, MAX(column_name) FROM table_name GROUP BY column_name; ``` **解析**:这里使用`MAX(column_name)`函数来获取每个分组中`...
- **MAX()**:找出指定列的最大值。 - **MIN()**:找出指定列的最小值。 例如,如果我们想知道每个客户的总订单金额,可以这样写: ```sql SELECT customer_id, SUM(order_amount) FROM orders GROUP BY ...
在本节中,我们将详细介绍 MySQL 中的分组函数和分组查询,包括 SUM、AVG、MAX、MIN 等函数,以及 GROUP BY 语句的使用。 一、分组函数 分组函数是 MySQL 中的一种聚合函数,用于对数据进行聚合和分析。常见的分组...
MySQL的GROUP BY语句是数据库查询中用于对数据进行分组和聚合操作的关键部分,它允许我们基于一个或多个字段的值对数据进行汇总。在本文中,我们将深入探讨GROUP BY的基本概念、语法以及如何使用它来处理多字段分组...
`GROUP BY`语句用于将数据表中的数据按照一个或多个列进行分组,以便对每个组进行聚合操作,如计算平均值(AVG)、总和(SUM)、最大值(MAX)、最小值(MIN)等。例如,如果你有一个包含商品信息和分类ID的表,你...
MySQL使用`GROUP BY`子句来实现这一功能。 - **基本用法**: - `SELECT column_name, aggregate_function(column_name) FROM table_name GROUP BY column_name;` - 示例:假设我们需要按性别分组并计算每个性别的...
MySQL中的`GROUP BY`语句是用于数据分组的关键语法,它允许你在多个记录中对相同字段值进行聚合。在数据库管理和分析中,`GROUP BY`通常与聚合函数(如`COUNT`, `SUM`, `AVG`, `MAX`, `MIN`)一起使用,帮助我们从...
在MySQL数据库中,`ORDER BY` 和 `GROUP BY` 是两个非常重要的子句,它们用于对查询结果进行排序和分组。理解它们的执行顺序对于优化SQL查询性能和编写正确的查询至关重要。 首先,我们来详细了解这两个子句的作用...
在MySQL中,`GROUP BY` 和 `HAVING` 通常一起用于聚合查询,用来筛选满足特定条件的分组。然而,当没有 `GROUP BY` 子句时,直接使用 `HAVING` 可能会导致非预期的行为。这个问题的探讨主要集中在 `HAVING` 后面直接...
在MySQL中,`GROUP_CONCAT` 是一个非常实用的聚合函数,它允许你在进行分组查询时,将相同分组内的多个字段值合并为一个单一的字符串,通常用于处理那些需要将多行数据整合到一行的情况。这个函数特别适用于那些需要...
- 使用`GROUP BY`子句按部门进行分组。 - 执行SQL语句:`cursor.execute(select_query)`。 5. **获取结果**:使用`cursor.fetchall()`获取查询结果。 6. **处理结果**:遍历查询结果,并打印每个部门及其对应的...
其中,IN操作符是判断某个值是否在子查询结果集中 ANY操作符是判断某个值是否等于子查询结果集中的最小值 ALL操作符是判断某个值是否等于子查询结果集中的最大值。 需要注意的是,使用NOT IN操作符时,如果集合范围...
1. GROUP BY子句可以包含任意数量的列,这意味着你可以根据多个列进行分组,实现更精细的数据划分。 2. 如果在GROUP BY中指定了多个列,数据会按照最后指定的列进行汇总。 3. GROUP BY中列出的所有列都必须是SELECT...