• 专注于网站建设,网络推广,关键词优化,SEO优化,专业的网站建设开发团队!
首页 > IT技术 > MySQL > 内容

MySQL group by 排序问题

2015-06-11 22:02:55   来源:叶景网络
    类如 有一个 帖子的回复表,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
叶景网络,网络推广,网站建设
特别推荐RECOMMEND
搜索引擎网站关键词seo优化的意义
视频推广怎么做
网站seo优化怎么做关键词排上首页?
SEO介绍什么叫搜索引擎网站关键词优化
seo优化怎样做提升关键词排名
热点图文Hot
MYSQL中导入大小超过2M的数据库文件解决办法 MYSQL中导入大小超
从MySQL中获得数据表auto_increment值的方法 从MySQL中获得数据
MySQL 错误1418 的原因分析及解决方法 MySQL 错误1418
MySQL group by 排序问题 MySQL group by 排序问题
关注排行RANKING
1

MYSQL中导入大小超过2M的数据库文件...

MYSQL中导入大小超过2M的数据库文件解决办法 叶景网络(www cngxit com),致力于互联网品牌建设与网络营销,专业领域包括网...

2

从MySQL中获得数据表auto_increment值的方法

从MySQL中获得数据表auto_increment值的方法 在插入一行数据前就想要知道将要产生的id。比如说想用来命名上传的文件。如果不事先...

3

MySQL 错误1418 的原因分析及解决方法

MySQL 错误1418 的原因分析及解决方法 叶景网络(www cngxit com),致力于互联网品牌建设与网络营销,专业领域包括网...

4

MySQL group by 排序问题

MySQL group by 排序问题 id 为 自动增长字段, tid为该回复的主题帖子的id(外键关联), subject 为回复...

5

MySQL-bin导致阿里云LNMP20G系统盘...

MySQL-bin导致阿里云LNMP20G系统盘不够用处理方法 在MySQL数据库中,mysql-bin 000001、mysql- bin 000002等文件是数据库的操作日志,...

6

LNMP更改网站文件和MySQL数据库的存放目录

LNMP更改网站文件和MySQL数据库的存放目录 购买阿里云服务器,一般建议买一个数据盘,也就是系统盘和数据盘分开,将网站文...

7

MySQL无法启动ERROR! MySQL is r...

MySQL无法启动ERROR! MySQL is running but PID file could not be found ? 叶景网络(www cngxit com),致力于互联网品牌建设与网络营销,专业领...

8

LNMP关闭MySQL日志保护硬盘空间

LNMP关闭MySQL日志保护硬盘空间 今天发现VPS硬盘居然快满了。第一反应是:肯定是某个东西的日志文件造成的,因为以前在W...

9

MySQL数据库批量修改表前缀的方法

MySQL数据库批量修改表前缀的方法 叶景网络(www cngxit com),致力于互联网品牌建设与网络营销,专业领域包括网...