Mysql group by 排序问题
类如 有一个 帖子的回复表,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弱智的地方,也许是我还没有发现,
期待高人拍砖!
Mysql group by 排序问题的更多相关文章
- MySQL Group Replication 技术点
mysql group replication,组复制,提供了多写(multi-master update)的特性,增强了原有的mysql的高可用架构.mysql group replication基 ...
- mysql group by 用法解析(详细)
在使用mysql时,有时需要查询出某个字段不重复的记录,虽然mysql提供 有distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用它来返回不重复记录的条数,而不是用它来返回不重记录的 ...
- (转载)mysql group by 用法解析(详细)
(转载)http://blog.tianya.cn/blogger/post_read.asp?BlogID=4221189&PostID=47881614 mysql distinct 去重 ...
- 细细探究MySQL Group Replicaiton — 配置维护故障处理全集
本文主要描述 MySQL Group Replication的简易原理.搭建过程以及故障维护管理内容.由于是新技术,未在生产环境使用过,本文均是虚拟机测试,可能存在考虑不周跟思路有误 ...
- MySQL Group Replication 动态添加成员节点
前提: MySQL GR 3节点(node1.node2.node3)部署成功,模式定为多主模式,单主模式也是一样的处理. 在线修改已有GR节点配置 分别登陆node1.node2.node3,执行以 ...
- MySQL Group Replication-MGR集群
简介 MySQL Group Replication(简称MGR)字面意思是mysql组复制的意思,但其实他是一个高可用的集群架构,暂时只支持mysql5.7和mysql8.0版本. 是MySQL官方 ...
- mysql group by组内排序
mysql group by组内排序: 首先是组外排序: SELECT z.create_time,z.invoice_id from qf_invoice_log z where z ...
- Docker Images for MySQL Group Replication 5.7.14
In this post, I will point you to Docker images for MySQL Group Replication testing. There is a new ...
- Percona XtraDB Cluster vs Galera Cluster vs MySQL Group Replication
Percona XtraDB Cluster vs Galera Cluster vs MySQL Group Replication Overview Galera Cluster 由 Coders ...
随机推荐
- 【转】select和epoll模型的差异
http://www.cppblog.com/converse/archive/2008/10/12/63836.html epoll为什么这么快 epoll是多路复用IO(I/O Multiplex ...
- purple-class2-默认选项切换
ylbtech-class:purple-class2 A, 返回顶部 1,默认选项切换 #region 默认选项切换 public delegate IList<SelectListItemI ...
- 使用thinkphp连接sqlserver数据库时提示“系统不支持:sqlsrv”
习惯了使用php跟mysql组合,现在接到项目需要调用客户线下的系统软件的数据,具了解,这个软件的数据库是用sqlserver数据库也就是常说的mssql数据库了. 那么我现在需要用PHP连接sqls ...
- URL编码CFURLCreateStringByAddingPercentEscapes使用(ARC)
URL 编码:CFURLCreateStringByAddingPercentEscapes If you have tried to send any information using a GET ...
- arraylist linkedlist性能测试
import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Ran ...
- uWSGI其三:uWSGI搭配Nginx使用
http://www.nowamagic.net/academy/detail/1330334 上一篇介绍了 uWSGI 来部署 Django 程序,但在在生产环境中单单只有 uWSGI 是不够的,N ...
- 在SoCEDS环境下编译和更新preloader和uboot程序的方法
在SoCEDS环境下编译和更新preloader和uboot程序的方法 前面有介绍preloader在HPS boot过程中的的作用,接下来讲述下用户在SoCEDS环境下改如何编译preloade ...
- blocksit
<!DOCTYPE html> <html> <head> <title>Sc.Chinaz.Com</title> & ...
- github里的gist是什么意思
在有关github的客户端中经常遇到gist这个词,如Gists->My Gists,Public Gists. 字典里解释gist为(发言.谈话或文章的)主旨,要点.百度百科的解释太恶心,我不 ...
- 解决Git报错:The current branch is not configured for pull No value for key branch.master.merge found in configuration
1.在本地工程目录找到config文件(我的是在D:\git\demo\.git):2.修改config文件内容为: [core] repositoryformatversion = 0 filemo ...