1. 类如 有一个帖子的回复表,posts id , tid , subject , message , dateline ,
  2.  
  3. id 自动增长字段, tid为该回复的主题帖子的id(外键关联), subject 为回复标题, message 为回复内容, dateline 为回复时间,用UNIX 时间戳表示,
  4.  
  5. 现在要求 选出 前十个来自不同主题的最新回复
  6.  
  7. SELECT * FROM posts GROUP BY tid LIMIT 10
  8.  
  9. 这样一个sql语句选出来的并非你想要的 最新的回复,而是最早的回复,实际上是某篇主题的第一条回复记录!
  10.  
  11. 也就是说 GROUP BY 语句没有排序,那么怎么才能让 GROUP 按照 dateline 倒序排列呢?加上 order by 子句?
  12.  
  13. 看下面:
  14.  
  15. SELECT * FROM posts GROUP BY tid ORDER BY dateline DESC LIMIT 10
  16.  
  17. 这条语句选出来的结果和上面的完全一样,不过把结果倒序排列 了,而选择出来的每一条记录仍然是上面的记录,原因是 group by 会比 order by 先执行,这样也就没有办法将 group by 之前,也就是在分组之前进行排序了, 有网友会写出下面的sql 语句:
  18.  
  19. SELECT * FROM posts GROUP BY tid DESC ORDER BY dateline DESC LIMIT 10
  20.  
  21. 也就是说 GROUP BY 的字段 tid 后面加上递减顺序,这样不就可以取得分组时的最后回复了吗?这个语句执行结果会和上面的一模一样,这里加上 DESC ASC对执行结果没有任何影响!其实这是一个错误的语句,原因是GROUP BY 之前并没有排序功能,mysql 手册上面说,GROUP BY 时是按照某种顺序排序的,某种顺序到底是什么顺序?其实根本没有顺序,因为按照tid分组,其实也就是说,把tid相等的归纳到一个组,这样想的话,GROUP BY tid DESC 可以认为是在按照 tid 分组的时候,按照tid进行倒序排列,这不扯吗,既然是按照tid分组,当然是tid相等的归到一组,而这时候按照tid倒叙还是升序有个P用!
  22.  
  23. 是有网友发明下面的语句:
  24.  
  25. SELECT * FROM posts GROUP BY tid , dateline DESC ORDER BY dateline DESC LIMIT 10
  26.  
  27. 想这样我就可以在分组前按照 dateline 倒序排列了,其实这个语句并没有起到按照tid分组的作用,原因还是上面的,在group by 字段后加 desc 还是 asc 是错误的写法,而这种写法 网友本意是想 按照 tid 分组,并且在分组的时候按照 dateline排倒序!而实际这句相当于下面的写法:(去掉 GROUP BY 字段后面的 DESC
  28.  
  29. SELECT * FROM posts GROUP BY tid , dateline ORDER BY dateline DESC LIMIT 10
  30.  
  31. 也就是说,按照 tid dateline 联合分组,只有在记录tiddateline 同时相等的时候才归纳到一组,这显然不可能,因为 dateline 时间线基本上是唯一的!
  32.  
  33. 有人写出下面的语句:
  34.  
  35. SELECT *,max(dateline) as max_line FROM posts GROUP BY tid ORDER BY dateline DESC LIMIT 10
  36.  
  37. 这条语句的没错是选出了最大发布时间,但是你可 以对比一下 dateline max_dateline 并不相等!(可能有相当的情况,就是分组的目标记录只有一条的时候!)
  38.  
  39. 什么呢?原因很简单,这条语句相当于是 group by 以后选出本组的最大的发布时间!对分组没有起到任何影响!因为SELECT子句是最后执行的!
  40.  
  41. 后来更有网友发明了下面的写法!
  42.  
  43. SELECT *,max(dateline) as max_line FROM posts GROUP BY tid HAVING dateline=max(dateline)
  44.  
  45. ORDER BY dateline DESC LIMIT 10
  46.  
  47. 这条语句的预期结果和想象中的并不相同!因为你会发现,分组的结果 中大量的记录没有了!为什么?因为 HAVING 是在分组的时候执行的,也就说:在分组的时候加上一个这样的条件:选择出来的 dateline 要和 本组最大的dateline 相等,执行的结果和下面的语句相同:
  48.  
  49. SELECT *,max(dateline) as max_line FROM posts GROUP BY tid HAVING count(*)=1
  50.  
  51. ORDER BY dateline DESC LIMIT 10
  52.  
  53. 了这条sql语句是不是明白了呢?
  54.  
  55. dateline=max(dateline) 只有在分组中的记录只有一条的时候才成立,原因很明白吧!只有一条他才会和本组的最大发布时间相等阿,(默认dateline为不重复的值)
  56.  
  57. 因还是因为 group by 并没有排序功能,所有的这些排序功能只是错觉,所以你最终选出的 dateline max(dateline) 永远不可能相等,除非本组的记录只有一条!GROUP BY 在分组的时候,可能是一个一个来找的,发现有相等的tid,去掉,保留第一个发现的那一条记录,所以找出来的记录永远只是按照默认索引顺序排列的!
  58.  
  59. 么说了这么多,到底有没有办法让 group by 执行前分组阿?有的 ,子查询阿!
  60.  
  61. 最简单的
  62.  
  63. SELECT * FROM (SELECT * FROM posts ORDER BY dateline DESC) GROUP BY tid ORDER BY dateline DESC LIMIT 10
  64.  
  65. 有网友利用自连接实现的 ,这样的效率应该比上面的子查询效率高,不过,为了简单明了,就只用这样一种了,GROUP BY没有排序功能,可能是mysql弱智的地方,也许是我还没有发现,
  66.  
  67. 期待高人拍砖!
  68.  
  69. 以上转之:http://www.alixixi.com/program/a/2011012867346.shtml
  70.  
  71. 我在按照作者的思路下解决了该麻烦,非常感谢作者啊!不过还有一点要注意,
  72.  
  73. SELECT * FROM (SELECT * FROM posts ORDER BY dateline DESC) 在这段代码后要为该查询语句起个别名,作表名使用,不然报错!
  74.  
  75. 完全正确的写法:
  76. SELECT * FROM (SELECT * FROM posts ORDER BY dateline DESC) BIAOMING GROUP BY tid ORDER BY dateline DESC LIMIT 10

关于MYSQL group by 分组按时间取最大值的实现方法!的更多相关文章

  1. 关于MYSQL group by 分组按时间取最大值的实现方法

    类如 有一个帖子的回复表,posts( id , tid , subject , message ,  dateline ) , id 为 自动增长字段, tid为该回复的主题帖子的id(外键关联), ...

  2. mysql group by分组查询后 查询个数

    mysql group by分组查询后 查询个数2个方法随便你选 <pre>select count(distinct colA) from table1;</pre>< ...

  3. Mysql Group by 分组取最小的实现方法

    表结构如下图:

  4. mysql group by分组查询

    分组的SQL语句有2个: group by 和分组聚合函数实现 partition by (oracle和postgreSQL中的语句)功能 group by + having 组合赛选数据 注意:h ...

  5. mysql 查找多个值并且取最大值一个和分组

    SELECT eco_truename, eco_uid, max(checkup_time) AS time FROM es_checkup_order WHERE checkup_time GRO ...

  6. 【mysql】【分组】后取每组的top2

    DROP TABLE IF EXISTS `tb1`; CREATE TABLE `tb1` ( `id` ) NOT NULL AUTO_INCREMENT, `a` ) DEFAULT NULL, ...

  7. mysql group by分组查询错误修改

    select @@global.sql_mode;set @@sql_mode ='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR ...

  8. 在mysql中使用group by和order by取每个分组中日期最大一行数据

    转载自:https://blog.csdn.net/shiyong1949/article/details/78482737 在mysql中使用group by进行分组后取某一列的最大值,我们可以直接 ...

  9. mysql单列去重复group by分组取每组前几条记录加order by排序

    mysql分组取每组前几条记录(排名) 附group by与order by的研究,需要的朋友可以参考下 --按某一字段分组取最大(小)值所在行的数据 复制代码代码如下: /* 数据如下: name ...

随机推荐

  1. C++之路进阶——bzoj1823(满汉全席)

    F.A.Qs Home Discuss ProblemSet Status Ranklist Contest ModifyUser  hyxzc Logout 捐赠本站 Notice:由于本OJ建立在 ...

  2. C++新手之详细介绍MFC

     MFC (Microsoft Foundation Class Library)中的各种类结合起来构成了一个应用程序框架,它的目的就是让程序员在此基础上来建立Windows下的应用程序,这是一种相对 ...

  3. 【皇甫】☀亲爱的~help me

     亲爱的,我不知道该怎么把我想对你说的话表达出来,希望我对你的认识真的像下面的内容一样,如果我有错,那说明我还不够了解你... 希望我们能够一起走到最后吧... 首先,说说最近的吧,  在我还没有和你 ...

  4. demo02TextView

    main.xml----- /layout/activity_main.xml <RelativeLayout xmlns:android="http://schemas.androi ...

  5. java 超经漂亮验证码

    package com.zly.xsp.image; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; im ...

  6. 夺命雷公狗---DEDECMS----21dedecms按照地区取出电影内容

    我们现在要做的就是: 这些电影都是要按照地区来取出才可以的,但是我们arclist标签里面有没有按照条件来查找的地方,我们只好换套路了,要不然条条大路都不通,,,, 我们先来构造一条语句: 他这个标签 ...

  7. linux下的网络配置

    临时生效的命令: 设置静态ip: ip addr add 192.168.1.2/24 dev eth0 设置网关: ip route add default via 192.168.1.1 启动某个 ...

  8. AC68U 内Linux 终端前后的切换,终端挂起和恢复

    ssh 登录终端后, 如果想切换到本地上来, 可以按: -,Ctrl+Z 如果要恢复到远程端,则命令: fg

  9. Linux内核配置机制(make menuconfig 、Kconfig、Makefile)讲解【转】

    本文转载自:http://www.codexiu.cn/linux/blog/34801/ 前面我们介绍模块编程的时候介绍了驱动进入内核有两种方式:模块和直接编译进内核,并介绍了模块的一种编译方式—— ...

  10. js获取IP地址方法总结_转

    js代码获取IP地址的方法,如何在js中取得客户端的IP地址.原文地址:js获取IP地址的三种方法 http://www.jbxue.com/article/11338.html 1,js取得IP地址 ...