程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> 關於MYSQL數據庫 >> Mysql的distinct語句和group by,order by

Mysql的distinct語句和group by,order by

編輯:關於MYSQL數據庫
最近,在做一個項目的時候,發現得出的數據於預料的相差很多,仔細的研究了一下,發現問題出在distinct語句和groupyby,orderby

  首先,distinct語句,獲得非重復的(唯一)行記.

  grouyby是分組,orderby是排序。

  直接看我的例子。

  假定我有一個表f_job,有字段:

selectjob_id,com_id,job_timefromf_job orderbyjob_timedesclimit10; Te:webwebPHPfhr  ee.txt
+--------+--------+---------------------+
|job_id|com_id|job_time      |
+--------+--------+---------------------+
| 5060| 2205|2006-09-2916:30:11|
| 4707| 19084|2006-09-2916:27:55|
| 4708| 19084|2006-09-2916:27:55|
| 4709| 19084|2006-09-2916:27:55|
| 4710| 19084|2006-09-2916:27:55|
| 4711| 19084|2006-09-2916:27:55|
| 4859| 19084|2006-09-2916:27:55|
| 4918| 19084|2006-09-2916:27:55|
| 5059| 2205|2006-09-2916:27:22|
| 4078| 2715|2006-09-2916:18:36|
+--------+--------+---------------------+
10rowsinset(0.03sec)

  還有其他字段,不可能影響結果.此處不列出。

  job_id是primarykey。com_id是外鍵,我需要按照時間來排序。所以必須使用orderby!

  你看到了com_id在得出的結果中不唯一,對,我需要的結果就是提取com_id唯一的最近10條com_id的記錄,而已。

  我就以以前的MSSQL的經驗寫如下的語句執行:

MySQL>selectdistinct(com_id)fromf_job orderbyjob_timedesclimit10; Te:webwebPHPfhr  ee.txt
+--------+
|com_id|
+--------+
| 19084|
| 2197|
| 19917|
| 19580|
| 19520|
| 19664|
| 19397|
| 19900|
| 1176|
| 19449|
+--------+

  對,這次得出的結果是唯一,但是,這不對呀,很明顯,把com_id記錄號碼是2005的記錄給沒了,這結果肯定錯。馬上分析一下所有的的結果,發現忽略的com_id並沒有消失,只是被排到後面去了。

  我按照時間排序,應該出現的結果第一個就是2205呀,為什麼能排到後面?從兩條可疑記錄看出了結果:

  原記錄:

| 5058| 19580|2006-09-2915:23:58|
| 5057| 19917|2006-09-2915:14:16|
| 4973| 19580|2006-09-2915:13:49|
| 5011| 19580|2006-09-2915:13:49|

  distinct後的次序:

| 19917|
| 19580|

  這說明,對於不是在一起的隔行記錄,如果恰巧隔一行,還可以被orderby比較出來,否則比較出來的不再真實,這是因為,被緩存的上次的orderby的臨時值在客觀上不再有用!還有一種情況,如果記錄連著,也可以被比較出來。

  先是明白了MySQL的弱智了。

 馬上又執行了一下操作,結果如下:

MySQL>selectdistinct(com_id),job_timefromf_job orderbyjob_timedesclimit10; 
+--------+---------------------+
|com_id|job_time      |
+--------+---------------------+
| 2205|2006-09-2916:30:11|
| 19084|2006-09-2916:27:55|
| 2205|2006-09-2916:27:22|
| 2715|2006-09-2916:18:36|
| 2197|2006-09-2916:03:16|
| 19580|2006-09-2915:23:58|
| 19917|2006-09-2915:14:16|
| 19580|2006-09-2915:13:49|
| 19520|2006-09-2910:29:41|
| 19900|2006-09-2910:16:48|
+--------+---------------------+
10rowsinset(0.10sec)

  先和這個比較一下:

MySQL>selectcom_id,job_timefromf_job orderbyjob_timedesclimit10; Te:webwebPHPfhr  ee.txt
+--------+---------------------+
|com_id|job_time      |
+--------+---------------------+
| 2205|2006-09-2916:30:11|
| 19084|2006-09-2916:27:55|
| 19084|2006-09-2916:27:55|
| 19084|2006-09-2916:27:55|
| 19084|2006-09-2916:27:55|
| 19084|2006-09-2916:27:55|
| 19084|2006-09-2916:27:55|
| 19084|2006-09-2916:27:55|
| 2205|2006-09-2916:27:22|
| 2715|2006-09-2916:18:36|
+--------+---------------------+
10rowsinset(0.06sec)

  發現,distinct恰巧和前面第一次測試的結果相反處理我們的信息,他把隔行的看作不同的結果輸出,這就導致了2205的記錄又出現了。

  然後我就用了groupby語句,應該可以吧,結果也讓我。。。:

MySQL>selectcom_idfromf_jobgroupbycom_id orderbyjob_timedesclimit10;
+--------+
|com_id|
+--------+
| 19084|
| 2197|
| 19917|
| 19580|
| 19520|
| 19664|
| 19397|
| 19900|
| 1176|
| 19449|
+--------+
10rowsinset(0.03sec)

  這和distinct的結果一樣,這倒不出乎意料,然後我又加入分組job_time,看看:

MySQL>selectcom_idfromf_jobgroupbycom_id,job_time orderbyjob_timedesclimit10;
+--------+
|com_id|
+--------+
| 2205|
| 19084|
| 2205|
| 2715|
| 2197|
| 19580|
| 19917|
| 19580|
| 19520|
| 19900|
+--------+
10rowsinset(0.03sec)

  這結果差一點點了,然後我再distinct(com_id)一下,應該可以了吧!看看:

MySQL>selectdistinct(com_id)fromf_jobgroupbycom_id,job_time orderbyjob_timedesclimit10; Te:webwebPHPfhr  ee.txt
+--------+
|com_id|
+--------+
| 19084|
| 2197|
| 19917|
| 19580|
| 19520|
| 19664|
| 19397|
| 19900|
| 1176|
| 19449|
+--------+
10rowsinset(0.04sec)

  汗,這和沒加groupby的一點區別都沒,怎麼這樣弱呀!沒辦法,這怎麼辦,猶豫中。。。

  上面的問題徹底的說明了這樣一個事實:distinct只能返回它的目標字段,而無法返回其它字段。。。

  汗,這和沒加groupby的一點區別都沒,怎麼這樣弱呀!沒辦法,這怎麼辦,猶豫中。。。

  ------------------------------------

  想起了一個很能騷的一個人--phzzy,這jh,QQ說了句話,果然在,他玩PHP,馬上求助,經過1個多小時的艱苦YY,終於這鳥人先大爺我一步給出語句:

  select(`com_id`),max(`job_time`)from`f_job`GROUPBY`com_id`orderbymax(`job_time`)limit10;

  mdgb,終於明白了,剛拿到這語句就明白了。

  我tmd知道這是2次排序,md,groupby是一次,然後無論怎麼樣,都不可能2次排序,因為第二次必須借助內部的集聚函數。。。。。。我怎麼沒想到max,氣死我了。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved