说Mysql的distinct语句和group by,order by
发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,最近,在做一个项目的时候,发现得出的数据于预料的相差很多,仔细的研究了一下,发现问题出在 distinct语句和groupy by,order by首先,distinct语句,获得非重复的(唯一)行记
千家信息网最后更新 2026年11月01日说Mysql的distinct语句和group by,order by最近,在做一个项目的时候,发现得出的数据于预料的相差很多,仔细的研究了一下,发现问题出在 distinct语句和groupy by,order by
首先,distinct语句,获得非重复的(唯一)行记.
grouy by是分组,order by 是排序。
直接看我的例子。
假定我有一个表f_job,有字段:
select job_id, com_id,job_time from f_job order by job_time desc limit 10; T e:webwebphpfhrtee.txt
+--------+--------+---------------------+
| job_id | com_id | job_time |
+--------+--------+---------------------+
| 5060 | 2205 | 2006-09-29 16:30:11 |
| 4707 | 19084 | 2006-09-29 16:27:55 |
| 4708 | 19084 | 2006-09-29 16:27:55 |
| 4709 | 19084 | 2006-09-29 16:27:55 |
| 4710 | 19084 | 2006-09-29 16:27:55 |
| 4711 | 19084 | 2006-09-29 16:27:55 |
| 4859 | 19084 | 2006-09-29 16:27:55 |
| 4918 | 19084 | 2006-09-29 16:27:55 |
| 5059 | 2205 | 2006-09-29 16:27:22 |
| 4078 | 2715 | 2006-09-29 16:18:36 |
+--------+--------+---------------------+
10 rows in set (0.03 sec)
还有其他字段,不可能影响结果.此处不列出。
job_id是primary key。 com_id是外键,我需要按照时间来排序。所以必须使用order by!
你看到了com_id在得出的结果中不唯一,对,我需要的结果就是提取com_id唯一的最近10条com_id的记录,而已。
我就以以前的MSSQL的经验写如下的语句执行:
mysql> select distinct( com_id) from f_job order by job_time desc limit 10; T e:webwebphpfhrtee.txt
+--------+
| com_id |
+--------+
| 19084 |
| 2197 |
| 19917 |
| 19580 |
| 19520 |
| 19664 |
| 19397 |
| 19900 |
| 1176 |
| 19449 |
+--------+
对,这次得出的结果是唯一,但是,这不对呀,很明显,把com_id记录号码是2005的记录给没了,这结果肯定错。马上分析一下所有的的结果,发现忽略的com_id并没有消失,只是被排到后面去了。
我按照时间排序,应该出现的结果第一个就是2205呀,为什么能排到后面?从两条可疑记录看出了结果:
原记录:
| 5058 | 19580 | 2006-09-29 15:23:58 |
| 5057 | 19917 | 2006-09-29 15:14:16 |
| 4973 | 19580 | 2006-09-29 15:13:49 |
| 5011 | 19580 | 2006-09-29 15:13:49 |
distinct后的次序:
| 19917 |
| 19580 |
这说明,对于不是在一起的隔行记录,如果恰巧隔一行,还可以被order by 比较出来,否则比较出来的不再真实,这是因为,被缓存的上次的order by 的临时值在客观上不再有用!还有一种情况,如果记录连着,也可以被比较出来。
先是明白了MySql的弱智了。
马上又执行了一下操作,结果如下: mysql> select distinct(com_id),job_time from f_job order by job_time desc limit 10;
+--------+---------------------+
| com_id | job_time |
+--------+---------------------+
| 2205 | 2006-09-29 16:30:11 |
| 19084 | 2006-09-29 16:27:55 |
| 2205 | 2006-09-29 16:27:22 |
| 2715 | 2006-09-29 16:18:36 |
| 2197 | 2006-09-29 16:03:16 |
| 19580 | 2006-09-29 15:23:58 |
| 19917 | 2006-09-29 15:14:16 |
| 19580 | 2006-09-29 15:13:49 |
| 19520 | 2006-09-29 10:29:41 |
| 19900 | 2006-09-29 10:16:48 |
+--------+---------------------+
10 rows in set (0.10 sec)
先和这个比较一下:
mysql> select com_id,job_time from f_job order by job_time desc limit 10; T e:webwebphpfhrtee.txt
+--------+---------------------+
| com_id | job_time |
+--------+---------------------+
| 2205 | 2006-09-29 16:30:11 |
| 19084 | 2006-09-29 16:27:55 |
| 19084 | 2006-09-29 16:27:55 |
| 19084 | 2006-09-29 16:27:55 |
| 19084 | 2006-09-29 16:27:55 |
| 19084 | 2006-09-29 16:27:55 |
| 19084 | 2006-09-29 16:27:55 |
| 19084 | 2006-09-29 16:27:55 |
| 2205 | 2006-09-29 16:27:22 |
| 2715 | 2006-09-29 16:18:36 |
+--------+---------------------+
10 rows in set (0.06 sec)
发现,distinct恰巧和前面第一次测试的结果相反处理我们的信息,他把隔行的看作不同的结果输出,这就导致了2205的记录又出现了。
然后我就用了group by语句,应该可以吧,结果也让我。。。:
mysql> select com_id from f_job group by com_id order by job_time desc limit 10;
+--------+
| com_id |
+--------+
| 19084 |
| 2197 |
| 19917 |
| 19580 |
| 19520 |
| 19664 |
| 19397 |
| 19900 |
| 1176 |
| 19449 |
+--------+
10 rows in set (0.03 sec)
这和distinct的结果一样,这倒不出乎意料,然后我又加入分组job_time,看看:
mysql> select com_id from f_job group by com_id,job_time order by job_time desc limit 10;
+--------+
| com_id |
+--------+
| 2205 |
| 19084 |
| 2205 |
| 2715 |
| 2197 |
| 19580 |
| 19917 |
| 19580 |
| 19520 |
| 19900 |
+--------+
10 rows in set (0.03 sec)
这结果差一点点了,然后我再distinct(com_id)一下,应该可以了吧!看看:
mysql> select distinct(com_id) from f_job group by com_id,job_time order by job_time desc limit 10; T e:webwebphpfhrtee.txt
+--------+
| com_id |
+--------+
| 19084 |
| 2197 |
| 19917 |
| 19580 |
| 19520 |
| 19664 |
| 19397 |
| 19900 |
| 1176 |
| 19449 |
+--------+
10 rows in set (0.04 sec)
汗,这和没加group by 的一点区别都没,怎么这样弱呀!没办法,这怎么办,犹豫中。。。
上面的问题彻底的说明了这样一个事实:distinct只能返回它的目标字段,而无法返回其它字段。。。
汗,这和没加group by 的一点区别都没,怎么这样弱呀!没办法,这怎么办,犹豫中。。。
------------------------------------
想起了一个很能骚的一个人--phzzy,这jh,qq说了句话,果然在,他玩php,马上求助,经过1个多小时的艰苦YY,终于这鸟人先大爷我一步给出语句:
select (`com_id`),max(`job_time`) from `f_job` GROUP BY `com_id` order by max(`job_time`) limit 10;
mdgb,终于明白了,刚拿到这语句就明白了。
我tmd知道这是2次排序,md,group by是一次,然后无论怎么样,都不可能2次排序,因为第二次必须借助内部的集聚函数。。。。。。我怎么没想到max,气死我了[@more@]
首先,distinct语句,获得非重复的(唯一)行记.
grouy by是分组,order by 是排序。
直接看我的例子。
假定我有一个表f_job,有字段:
select job_id, com_id,job_time from f_job order by job_time desc limit 10; T e:webwebphpfhrtee.txt
+--------+--------+---------------------+
| job_id | com_id | job_time |
+--------+--------+---------------------+
| 5060 | 2205 | 2006-09-29 16:30:11 |
| 4707 | 19084 | 2006-09-29 16:27:55 |
| 4708 | 19084 | 2006-09-29 16:27:55 |
| 4709 | 19084 | 2006-09-29 16:27:55 |
| 4710 | 19084 | 2006-09-29 16:27:55 |
| 4711 | 19084 | 2006-09-29 16:27:55 |
| 4859 | 19084 | 2006-09-29 16:27:55 |
| 4918 | 19084 | 2006-09-29 16:27:55 |
| 5059 | 2205 | 2006-09-29 16:27:22 |
| 4078 | 2715 | 2006-09-29 16:18:36 |
+--------+--------+---------------------+
10 rows in set (0.03 sec)
还有其他字段,不可能影响结果.此处不列出。
job_id是primary key。 com_id是外键,我需要按照时间来排序。所以必须使用order by!
你看到了com_id在得出的结果中不唯一,对,我需要的结果就是提取com_id唯一的最近10条com_id的记录,而已。
我就以以前的MSSQL的经验写如下的语句执行:
mysql> select distinct( com_id) from f_job order by job_time desc limit 10; T e:webwebphpfhrtee.txt
+--------+
| com_id |
+--------+
| 19084 |
| 2197 |
| 19917 |
| 19580 |
| 19520 |
| 19664 |
| 19397 |
| 19900 |
| 1176 |
| 19449 |
+--------+
对,这次得出的结果是唯一,但是,这不对呀,很明显,把com_id记录号码是2005的记录给没了,这结果肯定错。马上分析一下所有的的结果,发现忽略的com_id并没有消失,只是被排到后面去了。
我按照时间排序,应该出现的结果第一个就是2205呀,为什么能排到后面?从两条可疑记录看出了结果:
原记录:
| 5058 | 19580 | 2006-09-29 15:23:58 |
| 5057 | 19917 | 2006-09-29 15:14:16 |
| 4973 | 19580 | 2006-09-29 15:13:49 |
| 5011 | 19580 | 2006-09-29 15:13:49 |
distinct后的次序:
| 19917 |
| 19580 |
这说明,对于不是在一起的隔行记录,如果恰巧隔一行,还可以被order by 比较出来,否则比较出来的不再真实,这是因为,被缓存的上次的order by 的临时值在客观上不再有用!还有一种情况,如果记录连着,也可以被比较出来。
先是明白了MySql的弱智了。
马上又执行了一下操作,结果如下: mysql> select distinct(com_id),job_time from f_job order by job_time desc limit 10;
+--------+---------------------+
| com_id | job_time |
+--------+---------------------+
| 2205 | 2006-09-29 16:30:11 |
| 19084 | 2006-09-29 16:27:55 |
| 2205 | 2006-09-29 16:27:22 |
| 2715 | 2006-09-29 16:18:36 |
| 2197 | 2006-09-29 16:03:16 |
| 19580 | 2006-09-29 15:23:58 |
| 19917 | 2006-09-29 15:14:16 |
| 19580 | 2006-09-29 15:13:49 |
| 19520 | 2006-09-29 10:29:41 |
| 19900 | 2006-09-29 10:16:48 |
+--------+---------------------+
10 rows in set (0.10 sec)
先和这个比较一下:
mysql> select com_id,job_time from f_job order by job_time desc limit 10; T e:webwebphpfhrtee.txt
+--------+---------------------+
| com_id | job_time |
+--------+---------------------+
| 2205 | 2006-09-29 16:30:11 |
| 19084 | 2006-09-29 16:27:55 |
| 19084 | 2006-09-29 16:27:55 |
| 19084 | 2006-09-29 16:27:55 |
| 19084 | 2006-09-29 16:27:55 |
| 19084 | 2006-09-29 16:27:55 |
| 19084 | 2006-09-29 16:27:55 |
| 19084 | 2006-09-29 16:27:55 |
| 2205 | 2006-09-29 16:27:22 |
| 2715 | 2006-09-29 16:18:36 |
+--------+---------------------+
10 rows in set (0.06 sec)
发现,distinct恰巧和前面第一次测试的结果相反处理我们的信息,他把隔行的看作不同的结果输出,这就导致了2205的记录又出现了。
然后我就用了group by语句,应该可以吧,结果也让我。。。:
mysql> select com_id from f_job group by com_id order by job_time desc limit 10;
+--------+
| com_id |
+--------+
| 19084 |
| 2197 |
| 19917 |
| 19580 |
| 19520 |
| 19664 |
| 19397 |
| 19900 |
| 1176 |
| 19449 |
+--------+
10 rows in set (0.03 sec)
这和distinct的结果一样,这倒不出乎意料,然后我又加入分组job_time,看看:
mysql> select com_id from f_job group by com_id,job_time order by job_time desc limit 10;
+--------+
| com_id |
+--------+
| 2205 |
| 19084 |
| 2205 |
| 2715 |
| 2197 |
| 19580 |
| 19917 |
| 19580 |
| 19520 |
| 19900 |
+--------+
10 rows in set (0.03 sec)
这结果差一点点了,然后我再distinct(com_id)一下,应该可以了吧!看看:
mysql> select distinct(com_id) from f_job group by com_id,job_time order by job_time desc limit 10; T e:webwebphpfhrtee.txt
+--------+
| com_id |
+--------+
| 19084 |
| 2197 |
| 19917 |
| 19580 |
| 19520 |
| 19664 |
| 19397 |
| 19900 |
| 1176 |
| 19449 |
+--------+
10 rows in set (0.04 sec)
汗,这和没加group by 的一点区别都没,怎么这样弱呀!没办法,这怎么办,犹豫中。。。
上面的问题彻底的说明了这样一个事实:distinct只能返回它的目标字段,而无法返回其它字段。。。
汗,这和没加group by 的一点区别都没,怎么这样弱呀!没办法,这怎么办,犹豫中。。。
------------------------------------
想起了一个很能骚的一个人--phzzy,这jh,qq说了句话,果然在,他玩php,马上求助,经过1个多小时的艰苦YY,终于这鸟人先大爷我一步给出语句:
select (`com_id`),max(`job_time`) from `f_job` GROUP BY `com_id` order by max(`job_time`) limit 10;
mdgb,终于明白了,刚拿到这语句就明白了。
我tmd知道这是2次排序,md,group by是一次,然后无论怎么样,都不可能2次排序,因为第二次必须借助内部的集聚函数。。。。。。我怎么没想到max,气死我了[@more@]
结果
语句
排序
字段
马上
犹豫
办法
就是
怎么办
时间
这是
问题
分组
不同
明显
艰苦
可疑
出乎意料
没想到
这不
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
互联网科技名片
山东特亿宝互联网科技有限公司
科技平台互联网
互联网最新的科技
互联网科技的
致骋互联网科技
世界互联网领先科技成果
浩特互联网科技
长亮科技 互联网金融
滨湖区互联网智能科技产品供应
成都仁贤领冠互联网科技有限公司
互联网科技博主是什么意思
移动互联网科技公司
洛阳共同富裕互联网科技有限公司
威龙国际互联网科技公司
四川互联网展示科技馆设计
互联网领先科技宣传片
35岁以上互联网科技行业
互联网科技手抄报图片
如何强化互联网金融科技
哈尔滨大商圈互联网科技有限公司
无线互联网科技
互联网科技ppt模板
成都玖崟互联网科技有限公司乐商圈怎么样
隆华科技工业互联网
东营紫格互联网科技
广东鹅鹅鹅互联网科技有限公司
互联网科技机房
湖北辰鑫科技互联网
银川新华互联网科技学校招聘