一:DISTINCT
在使用mysql時,有時需要查詢出某個字段不重復的記錄,雖然mysql提供有distinct這個關鍵字來過濾掉多余的重復記錄只保留一條,但往往只用它來返回不重復記錄的條數,而不是用它來返回不重記錄的所有值。其原因是distinct只能返回它的目標字段,而無法返回其它字段,這個問題讓我困擾了很久,用distinct不能解決的話,我只有用二重循環查詢來解決,而這樣對於一個數據量非常大的站來說,無疑是會直接影響到效率的。所以我花了很多時間來研究這個問題,網上也查不到解決方案,但最終還是解決了。下面來看一個例子,看看我解決的心路歷程!
1.數據庫表(tms_sgoods)
表結構大概這個樣子,這只是一個簡單的例子,實際情況會復雜很多。
比如我想用一條語句查詢到SORDER_NO不重復的所有數據,那就必須使用distinct去掉多余的重復記錄。
SELECT DISTINCT SORDER_NO FROM tms_sgoods
得到的結果是:
好像達到了效果,可是,我想要得到的是id值呢?改一下查詢語句吧:
SELECT DISTINCT SORDER_NO,SGOODS_ID FROM tms_sgoods
結果是:
distinct怎么沒有起作用?作用是起了,不過它同時作用了兩個字段,也就是必須得SGOODS_ID與SORDER_NO都相同時才會被排除。。。
我們再改改查詢語句:
SELECT SGOODS_ID,DISTINCT SORDER_NO FROM tms_sgoods
很遺憾,除了錯誤信息你什么也得不到,distinct必須放在開頭。難到不能把distinct放到where條件里?能,照樣報錯。。。。。。。
很麻煩吧?確實,費盡心思都沒有解決這個問題。沒辦法,繼續找人問。試了半天,還是不行,最后在mysql手冊里找到一個用法,用group_concat(distinct SORDER_NO)配合group by SORDER_NO實現了我所需要的功能,興奮,天佑我也。
SELECT SGOODS_ID,GROUP_CONCAT(DISTINCT SORDER_NO) FROM tms_sgoods GROUP BY SORDER_NO
結果是:
注意:group_concat函數是4.1支持的。終於搞定了,不過這樣一來,如果是給客戶部署的怎么辦?因此只能要求客戶也升級了。
突然一想,既然可以使用group_concat函數,那其它函數能行嗎?趕緊用count函數一試,成功,我。。。。。。。想哭啊,費了這么多工夫。。。。。。。。原來就這么簡單……
SELECT *,COUNT(DISTINCT SORDER_NO) FROM tms_sgoods GROUP BY SORDER_NO
結果是:
最后一項是多余的,不用管就行了,目的達到。
更郁悶的是:突然發現有更簡單的解決方法:
SELECT *FROM tms_sgoods GROUP BY SORDER_NO
結果是:
看來對mysql的了解還是太膚淺了,不怕被笑話,發出來讓大家別犯同樣的錯誤。
二:GROUP BY
表結構和數據如下:
1.列出每個部門最高薪水
SELECT DEPT,MAX(SALARY) AS MAXSALARY FROM tms_sgoods GROUP BY DEPT
結果如下:
2.查詢每個部門的總薪水數
SELECT DEPT,SUM(SALARY) AS TOTAL FROM tms_sgoods GROUP BY DEPT
結果如下:
3.查詢公司2016年入職的各個部門每個級別里的最高薪水
SELECT DEPT,EDLEVEL,MAX(SALARY) AS MAXSALARY FROM tms_sgoods
WHERE HIREDATE >='2016-07-08'
GROUP BY DEPT, EDLEVEL
ORDER BY DEPT, EDLEVEL
結果如下:
三:CONCAT()函數
CONCAT()函數用於將多個字符串連接成一個字符串。
使用數據表info作為示例,其中 select id,name from info limit 1;返回的結果是:
1.語法及使用特點
CONCAT(str1,str2,...)
返回結果為連接參數產生的字符串。如果任何一個參數為NULL,則返回值為NULL。可以有一個或多個參數。
2.使用示例:select concat(id,',',name)as con from info limit 1;返回結果為:
select concat('My',NULL,'QL');返回結果為
3.如何指定參數之間的分隔符
使用函數CONCAT_WS()。使用語法為:CONCAT_WS(separator,str1,str2,...)
CONCAT_WS()代表CONCAT With Separator,是CONCAT()的特殊形式。第一個參數是其他參數的分隔符。分隔符的位置放在要連接的兩個字符串之間。分隔符可以是一個字符串,也可以是其他參數。如果分隔符是NULL,則結果為NULL。函數會忽略任何分隔符參數后的NULL值。但是CONCAT_WS()不會忽略任何空字符串。
如select CONCAT_WS('_',id,name) as con_ws from info limit 1;返回結果為:
select CONCAT_WS(',','first name',NULL,'last name');返回結果為:
四:GROUP_CONCAT()函數
這個函數能將相同的行組合起來,即所謂的行轉列。完整語法如下:
group_concat([DISTINCT]要連接的字段[order by ASC/DESC排序字段][Separator'分隔符'])