在使用mysql時,有時需要查詢出某個字段不重復的記錄,雖然mysql提供 有distinct這個關鍵字來過濾掉多余的重復記錄只保留一條,但往往只用它來返回不重復記錄的條數,而不是用它來返回不重記錄的所有值。其原因是 distinct只能返回它的目標字段.
而無法返回其它字段,這個問題讓我困擾了很久,用distinct不能解決的話,我只有用二重循環查詢來解決,而 這樣對于一個數據量非常大的站來說,無疑是會直接影響到效率的。所以我花了很多時間來研究這個問題
mysql的DISTINCT的關鍵字有很多你想不到的用處
1.在count 不重復的記錄的時候能用到,比如SELECT COUNT( DISTINCT id ) FROM tablename;就是計算talbebname表中id不同的記錄有多少條
2,在需要返回記錄不同的id的具體值的時候可以用,比如SELECT DISTINCT id FROM tablename;返回talbebname表中不同的id的具體的值
3.上面的情況2對于需要返回mysql表中2列以上的結果時會有歧義,比如SELECT DISTINCT id, type FROM tablename;
實際上返回的是 id與type同時不相同的結果,也就是DISTINCT同時作用了兩個字段,必須得id與tyoe都相同的才被排除了,與我們期望的結果不一樣.
例,代碼如下:
- CREATE TABLE `student` (
- `name` varchar(20) NOT NULL DEFAULT '',
- `age` int(10) DEFAULT '0'
- ) ENGINE=InnoDB DEFAULT CHARSET=latin1
- --1.測試一
- select * from student;
- a 5
- a 5
- c 0
用distinct過濾掉兩列都相同的記錄,代碼如下:
- select distinct name,age from student;
- --返回
- a 5
- c 0
2.測試二
將表student的數據改為如下,代碼如下:
- select * from student;
- c 2
- c 5
- select distinct name,age from student;
返回如下,說明distinct后面有多于一列的字段時,只有每列的值完全相同才過濾.
c 2
c 5
3.測試三,代碼如下:
- select * from student;
- name age height
- --Vevb.com
- c 2 123
- c 2 456
- b 20 222
group by按兩列同時分組,代碼如下:
- select name,age,sum(height) from student group by name,age;
- b 20 222
- c 2 579
group by按兩列同時分組,同時在后面加上having的條件,代碼如下:
select name,age,sum(height) as n from student group by name,age having n > 500;
返回:c 2 579
4.測試四
關于group by后面limit的測試,代碼如下:
- select songname,sengerid,count(sengerid) as n from t_song group by songname,sengerid having n > 1 ORDER BY n DESC,songid ASC limit 10;
- 未知 8738 40
- 共同渡過 1432 24
- 風繼續吹 1432 23
- 倩女幽魂 1432 23
- 無心睡眠 1432 23
- 羅百吉超嗨派對連續組曲 780 19
- 拒絕再玩 1432 19
- 風再起時 1432 18
- 每天愛你多一些 1480 18
- 千言萬語 1794 18
- select songname,sengerid,count(sengerid) as n from t_song group by songname,sengerid having n > 1 ORDER BY n DESC,songid ASC limit 5;
- 未知 8738 40
- 共同渡過 1432 24
- 風繼續吹 1432 23
- 倩女幽魂 1432 23
- 無心睡眠 1432 23
經過以上兩個測試可以看出,如果sql語句中含有limit,limit是對用group by進行分組,并進行相關計算以后的limit操作,而不是對limit后面的指定記錄數進行分組,從n那一列的數據每一行的值都大于10就可以看出來.
5.測試五
用以下的兩種形式的distinct均可以得到相同的記錄數,寫法不一樣,結果是一樣的,代碼如下:
select count(distinct(songid)) from feedback;
select count(distinct songid) from feedback;
6.測試六
field singername is string,max(singername),如果singername有些列為空,有些列不為空,則max(singername)取非空的值,如果一列為zxx,一列為lady,則取zxx,按字母順利取的,代碼如下:
select feedback_id,songid,songname,max(singername),max(time) as new_time from feedback group by songid order by new_time desc;
7.Sql語句中where,group by,order by及limit的順序
where xxx,group by xxx,order by xxx,limit xxx
8.關于group by與count的問題
如果sql語句中含有group by,則最好不要將count sql轉換為select count(*) from xxx,否則select與from之間的字段很有可能是后面要使用的,代碼如下:
- select feedback_id,songid,songname,max(singername),max(time) as new_time from feedback group by songid order by new_time desc;
- MySQL Query Error: SELECT COUNT(*) FROM feedback GROUP BY songid ORDER BY new_time DESC Error Info:Unknown column 'new_time' in 'order clause'
新聞熱點
疑難解答