网页教学网
 当前位置: 网页教学网 >> 网络编程 >> 数据库编程技术 >> Mysql的distinct语句和group by,order by
[ HTML ] [ FW ] [ DW ] [ FP ] [ JS ] [ XML ] [ CSS ] [ 图象 ] [ FLASH ] [ .NET ] [ ASP ] [ JSP ] [ PHP ] [ 数据 ] [ 系统 ] [ 安全 ] [ 素材 ] [ 建站 ] [ 主机 ] [ 入门 ] [ 技巧 ]

Mysql的distinct语句和group by,order by

http://www.webjx.com  更新日期:2007-09-17 07:57  出处:网页教学网  作者:
  最近,在做一个项目的时候,发现得出的数据于预料的相差很多,仔细的研究了一下,发现问题出在 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:\web\web\php\fhr\tee.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:\web\web\php\fhr\tee.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:\web\web\php\fhr\tee.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:\web\web\php\fhr\tee.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,气死我了。
关键词:数据库,MYSQL
推荐给好友】【关闭】【收藏本文
最新五条评论
查看全部评论
评论总数 0
您的评论
用户名: 新注册) 密 码: 匿名:
·用户发表意见仅代表其个人意见,并且承担一切因发表内容引起的纠纷和责任
·本站管理人员有权在不通知用户的情况下删除不符合规定的评论信息或留做证据
·请客观的评价您所看到的资讯,提倡就事论事,杜绝漫骂和人身攻击等不文明行为
站内搜索
相关文章
推荐文章