我的一亩三分地 我就喜欢!
13fen  设为主页
 收藏本站
 
当前位置: > 一亩三分地:首页 > 综合文库 > 数据库 > MySql > Mysql的distinct语句和group by,order by
热门文章排行
热门文章排行 MySQL服务器的启动与停止(12-15)
如何将Access和Excel导入到Mysql中之(11-16)
如何将Access和Excel导入到Mysql中之(11-16)
DBI/mysql FAQ(11-21)
redhat8 mysql安装具体过程(12-15)
精采文章排行
精采文章排行 用于 SELECT 和 WHERE 子句的函数(11-16)
数据操纵:SELECT, INSERT, UPDATE, (11-16)
数据定义:CREATE、DROP、ALTER(11-16)
基本的 MySQL 用户实用命令(11-16)
MySQL数据的导出和导入工具:mysqldum(11-16)
技术专题推荐
网管论坛交流
 

Mysql的distinct语句和group by,order by 

作者:   来源:   点击:   日期:2007-11-21

最近,在做一个项目的时候,发现得出的数据于预料的相差很多,仔细的研究了一下,发现问题出在 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  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,气死我了。



文章评论】 【收藏本文】 【推荐好友】 【打印本文】 【论坛讨论

   相关文章:
·如何在Windows上安装多个Mysql ·使用DB2look重新创建优化器访问计划
·用mysql做站点时怎样记录未知错误的发生 ·运用Mysql语句生成后门木马的具体方法
·精细讲解最简便的备份MySQL数据库的方法 ·用MySQL创建数据库和数据库表

   文章评论:(条)
  
 请留名: 匿名评论   点击查看所有评论 网管论坛
 

  责任编辑:一分  声明:刊登此文章是为了传递更多信息,文章内容仅供参考,转载请注明出处。