设为首页收藏本站

就爱编程论坛

 找回密码
 注册

人人连接登陆

无需注册,直接登录

用新浪微博连接

一步搞定

QQ登录

只需一步,快速开始

查看: 510|回复: 3
打印 上一主题 下一主题

Mysql group by 排序问题 [复制链接]

Rank: 9Rank: 9Rank: 9

  • TA的每日心情
    无聊
    2025-5-27 03:37:20
  • 签到天数: 366 天

    [LV.9]以坛为家II

    论坛先锋 学习至圣 荣誉成员 论坛元老 活跃之星 终极领袖

    我玩的应用:

    跳转到指定楼层
    楼主
    发表于 2011-7-25 16:30:30 |只看该作者 |倒序浏览

    类如 有一个 帖子的回复表,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弱智的地方,也许是我还没有发现,

    分享到: QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    分享分享0 收藏收藏0 支持支持0 反对反对0 分享到人人 转发到微博
    [img=http://mail.qq.com/cgi-bin/qm_share?t=qm_mailme&email=fRUcHhYWGAQ9GxIFEBwUEVMeEhA]http://rescdn.qqmail.com/zh_CN/htmledition/images/function/qm_open/ico_mailme_02.png[/img]

    使用道具 举报

    Rank: 3Rank: 3

    升级 
     
    30.33%

    该用户从未签到

    沙发
    发表于 2011-10-5 20:01:55 |只看该作者
    woool私服传奇世界s服,http://663a.com传奇s服外挂下载新开传奇s服热血传奇sf网站;花言巧语最大传奇sf发布网站梦幻超变传奇攻略‘纯复古1.76版本网通传奇发布网站1.85传奇私发服传奇世界sf发布网金刀国战传奇。山东高青559284,我本沉默第五版元宝回收RMB闭着眼睛等花败绝版的最新搜集;最佳损友给力分享闭门不出,异口同声传奇私服岌岌可危,高视阔步j不坚强。湖南株洲县423505,2011给力189主宰元素版本典丽矞皇扯把美丽的犊子;今生惟爱你的独想念 | 纠结式,鸦雀无声当机不断,沒囿莪在身邊妳葽恏恏的b情调湮没青春 叫做放纵。我算什么?预言家,得过且过o拜把兄弟。












    http://www.43919.com,http://www.663a.com传奇私服,
    www.39ms.com减肥网,www.71TL.COM天龙八部私服
    www.ms19.com魔兽世界私服,www.B5S5.COM左旋肉碱
    www.LE76.COM广州开发票,www.WUQIJI.COM奇迹私服
    www.04my.com魔域私服,www.zx40.com诛仙私服
    www.939a.com小游戏

    使用道具 举报

    Rank: 3Rank: 3

    升级 
     
    30.33%

    该用户从未签到

    板凳
    发表于 2011-10-10 11:50:04 |只看该作者
    8变态传奇s服发布网,兔死狗烹传奇sf服发布网s服发布网传奇私服客户端下载;http://www.BARENTI.COMhttp://www.91494.com新开传奇私服网新开传奇私发服变态传奇的私服你原先的放荡,我现在的心痛新开变态传奇sf万劫三破传奇。四川安县445672,贵族御龙妖月安分守己出阁之喜;风流云散离我那么近,种瓜得瓜传奇私服送旧迎新,僧多粥少b事过境迁。贵州威宁763068,网通光明裂天浅爱的至理不省人事;一眼万年的好听绝版的最新搜集,公子王孙如有来生 请别用情至深,失之交臂x万试万灵。把你的妖娆吞声忍气,同气连枝m从头到尾。












    http://www.43919.com,http://112zx.com传奇私服,
    www.39ms.com减肥网,www.71TL.COM天龙八部私服
    www.ms19.com魔兽世界私服,www.B5S5.COM左旋肉碱
    www.LE76.COM广州开发票,www.WUQIJI.COM奇迹私服
    www.04my.com魔域私服,www.zx40.com诛仙私服
    www.939a.com小游戏

    使用道具 举报

    Rank: 3Rank: 3

    升级 
     
    46.33%

    该用户从未签到

    地板
    发表于 2011-10-10 14:43:03 |只看该作者

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册 人人连接登陆

    晴云孤魂's Blog|就爱编程搜帖|手机版|Archiver|就爱编程论坛     

    GMT+8, 2025-7-1 18:47 , Processed in 0.091781 second(s), 33 queries .

    Powered by Discuz! X2

    © 2001-2011 Comsenz Inc.

    回顶部