mysql分组取最新的⼀条记录(整条记录)
⽅法:mysql取分组后最新的⼀条记录,下⾯两种⽅法.⼀种是先筛选出最⼤和最新的时间,在连表查询.⼀种是先排序,然后在次分组查询(默认第⼀条),就是最新的⼀条数据了
#select*from t_assistant_article as a, (select max(base_id) as base_id, max(create_time) as create_time from t_assistant_article as b group by base_id ) as b where a.base_id=b.base_id ate_time = b.create_time #select base_id,max(create_time), max(article_id) as article_id from t_assistant_article as b group by base_id
select*from (select*from t_assistant_article order by create_time desc) as a group by base_id order by create_time desc
来源:blog.csdn/swweb/article/details/11059037
mysql "group by"与"order by"的研究--分类中最新的内容 www.jb51/article/23969.htm
在使⽤mysql排序的时候会想到按照降序分组来获得⼀组数据,⽽使⽤order by往往得到的不是理想中的结果,那么怎么才能使⽤group by 和order 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 先执⾏,这样也就没有办法将
mysql删除重复的数据保留一条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:729038198,我们将在24小时内删除。
发表评论