老尸 发表于 2015-1-16 22:14:16

MYSQL编程:Mysql group by 排序成绩

人们常说“成功孕育成功”,这种说法明显非常适合MySQL的情况。MySQL学习教程这个开源数据库号称在全世界有超过110万份的完全安装。类如有一个帖子的复兴表,posts(id,tid,subject,message,dateline),

id为主动增加字段,tid为该复兴的主题帖子的id(外键联系关系),subject为复兴题目,message为复兴内容,dateline为复兴工夫,用UNIX工夫戳暗示,

如今请求选出前十个来自分歧主题的最新复兴


SELECT*FROMpostsGROUPBYtidLIMIT10


如许一个sql语句选出来的并不是你想要的最新的复兴,而是最早的复兴,实践上是某篇主题的第一条复兴纪录!

也就是说GROUPBY语句没有排序,那末怎样才干让GROUP依照dateline倒序分列呢?加上orderby子句?

看上面:

SELECT*FROMpostsGROUPBYtidORDERBYdatelineDESCLIMIT10


这条语句选出来的了局和下面的完整一样,不外把了局倒序分列了,而选择出来的每笔记录仍旧是下面的纪录,缘故原由是groupby会比orderby先实行,如许也就没有举措将groupby之前,也就是在分组之行进行排序了,有网友会写出上面的sql语句:


SELECT*FROMpostsGROUPBYtidDESCORDERBYdatelineDESCLIMIT10


也就是说在GROUPBY的字段tid前面加上递加按次,如许不就能够获得分组时的最初复兴了吗?这个语句实行了局会和下面的千篇一律,这里加上DESC和ASC对实行了局没有任何影响!实在这是一个毛病的语句,缘故原由是GROUPBY之前并没有排序功效,mysql手册下面说,GROUPBY时是依照某种按次排序的,某种按次究竟是甚么按次?实在基本没有按次,由于依照tid分组,实在也就是说,把tid相称的归结到一个组,如许想的话,GROUPBYtidDESC能够以为是在依照tid分组的时分,依照tid举行倒序分列,这不扯吗,既然是依照tid分组,固然是tid相称的回到一组,而这时候候依照tid倒叙仍是升序有个P用!


于是有网友创造上面的语句:


SELECT*FROMpostsGROUPBYtid,datelineDESCORDERBYdatelineDESCLIMIT10


心想如许我就能够在分组前依照dateline倒序分列了,实在这个语句并没有起到依照tid分组的感化,缘故原由仍是下面的,在groupby字段后加desc仍是asc是毛病的写法,而这类写法网友本意是想依照tid分组,而且在分组的时分依照dateline排倒序!而实践这句相称于上面的写法:(往失落GROUPBY字段前面的DESC)


SELECT*FROMpostsGROUPBYtid,datelineORDERBYdatelineDESCLIMIT10


也就是说,依照tid和dateline团结分组,只要在纪录tid和dateline同时相称的时分才归结到一组,这明显不成能,由于dateline工夫线基础上是独一的!


有人写出上面的语句:


SELECT*,max(dateline)asmax_lineFROMpostsGROUPBYtidORDERBYdatelineDESCLIMIT10


这条语句的没错是选出了最年夜公布工夫,可是你可以对照一下dateline和max_dateline其实不相称!(大概有相称的情形,就是分组的方针纪录只要一条的时分!)


为甚么呢?缘故原由很复杂,这条语句相称因而在groupby今后选出本组的最年夜的公布工夫!对分组没有起就任何影响!由于SELECT子句是最初实行的!

厥后更有网友创造了上面的写法!


SELECT*,max(dateline)asmax_lineFROMpostsGROUPBYtidHAVINGdateline=max(dateline)


ORDERBYdatelineDESCLIMIT10


这条语句的预期了局和设想中的其实不不异!由于你会发明,分组的了局中大批的纪录没有了!为何?由于HAVING是在分组的时分实行的,也就说:在分组的时分加上一个如许的前提:选择出来的dateline要和本组最年夜的dateline相称,实行的了局和上面的语句不异:


SELECT*,max(dateline)asmax_lineFROMpostsGROUPBYtidHAVINGcount(*)=1


ORDERBYdatelineDESCLIMIT10


看了这条sql语句是否是分明了呢?

dateline=max(dateline)只要在分组中的纪录只要一条的时分才建立,缘故原由很分明吧!只要一条他才会和本组的最年夜公布工夫相称阿,(默许dateline为不反复的值)


原因仍是由于groupby并没有排序功效,一切的这些排序功效只是错觉,以是你终极选出的dateline和max(dateline)永久不成能相称,除非本组的纪录只要一条!GROUPBY在分组的时分,多是一个一个来找的,发明有相称的tid,往失落,保存第一个发明的那一笔记录,以是找出来的纪录永久只是依照默许索引按次分列的!


那么说了这么多,究竟有无举措让groupby实行前分组阿?有的,子查询阿!


最复杂的:


SELECT*FROM(SELECT*FROMpostsORDERBYdatelineDESC)GROUPBYtidORDERBYdatelineDESCLIMIT10


也有网友使用自毗连完成的,如许的效力应当比下面的子查询效力高,不外,为了复杂了然,就只用如许一种了,GROUPBY没有排序功效,多是mysql弱智的中央,大概是我还没有发明,

等候高人拍砖!
<Pstyle="TEXT-INDENT:2em">
每个人都在使用它。MySQL是开源LAMP组合的一个标准组件:Linux、Apache、MySQL和Perl/PHP。根据Evans的调查,LAMP组合的迅速推广很大程度上代表着MySQL的被广泛接受。

灵魂腐蚀 发表于 2015-1-19 05:52:46

记得在最开始使用2k的时候就要用到这个功能,可惜2k没有,现在有了作解决方案的朋友会很高兴吧。

因胸联盟 发表于 2015-2-2 05:00:12

原理很简单,对要求长时间计算某一时间点的报表生成和防用户操作错误很有帮助。但是比起Oracle10g的闪回技术还是细粒度不够。可惜!

深爱那片海 发表于 2015-2-7 16:35:20

个人感觉没有case直观。而且默认的第三字段(还可能更多)作为groupby字段很容易造成新手的错误。

海妖 发表于 2015-2-22 16:25:16

入门没那么困难,精通没那么容易

爱飞 发表于 2015-3-7 01:32:16

是否碎片会引发效率问题?这都是需要进一步探讨的东西。varbinary(max)代替image也让SQLServer的字段类型更加简洁统一。

莫相离 发表于 2015-3-14 05:18:10

SP4包括用于以下SQLServer2000组件的程序包:Database组件(下载文件:SQL2000-KB884525-SP4-x86.EXE)更新SQLServer2000的32位Database组件,包括数据库引擎、复制、客户端连接组件及工具。有关其他信息,请参阅ReadmeSql2k32Sp4.htm。AnalysisServices组件(下载文件:SQL2000.AS-KB884525-SP4-x86.EXE)更新SQLServer2000的32位AnalysisServices。

山那边是海 发表于 2015-3-21 00:37:20

习惯敲命令行的朋友可能会爽一些。但是功能有限。适合机器跑不动SQLServerManagementStudio的朋友使用。
页: [1]
查看完整版本: MYSQL编程:Mysql group by 排序成绩