出處:http://javeye.iteye.com/blog/558093
我們知道,group by可以將sql查詢結果按照group by後面列進行分類顯示。比如:
- select columnA,columnB from table group by columnA,columnB
則查詢結果將按照columnA和columnB分類顯示。沒有顯示在group by中的列不能直接作爲返回列放在sql語句中,比如如下sql就是不正確的
- select columnA,columnC from table group by columnA
由於columnC不在group by的範圍之類,所以這樣寫是不對的,所幸的是,group by支持一些sql 函數的使用,比如SUM,AVG,COUNT等等。這些都比較常用,今天我要記錄下的是這個不常用的GROUP_CONCAT。
有一個需求,需要用到group by 才能實現,可是,我同是還需要返回某列的所有結果,(注意,不是做avg,sum等操作,我要枚舉這列的所有結果),那麼就可以用到GROUP_CONCAT。
舉個例子:
我有一張數據庫表結構如下:
列名 | 含義 |
year | 年份 |
month | 月份 |
volumn | 期數 |
該表存儲了某雜誌的年份,月份和期數。如果需求對該表內容作如下顯示:
2010年12月 | 第1期 第2期 第3期 第4期 |
2010年11月 | 第1期 第2期 第3期 第4期 第5期 |
2010年10月 | 第1期 第2期 第3期 第4期 |
2010年9月 | 第1期 第2期 第3期 第4期 第5期 |
2010年8月 | 第1期 第2期 第3期 第4期 |
sql該怎麼寫呢?按照年份和月份做group by?然後按照年份和月份做倒敘排列?
- select year,month from magazine group by year,month order by year desc,month desc
那具體的期數信息就丟了?能不能做group by的時候,還能返回在某個年份year和月份month分組下的所有期數volumn信息?(某個年份+月份下的期數信息是不固定的,只能通過數據庫查詢才能獲得)
該是GROUP_CONCAT上陣的時候了。
- select year,month GROUP_CONCAT(volumn) from magazine group by year,month order by year desc, month desc
這樣,查詢的返回結果類似於:
year | month | GROUP_CONCAT(volumn) |
2010 | 12 | 1,2,3,4 |
2010 | 11 | 1,2,3,4,5 |
不錯吧?
還有點問題需要補充下,就是作爲GROUP_CONCAT函數參數的字段,如過返回值爲string,則上面的sql語句已經沒有問題,但是如果是number,則返回的GROUP_CONCAT(volumn)值爲BLOB類型(其實上面例子返回的就是一個blob類型,我只是爲了演示的方便),需要做一下轉化。
- select year,month GROUP_CONCAT(conv( oct( volumn ) , 8, 10 )) from magazine group by year,month order by year desc, month desc
上面的sql對volumn做了一個從8進制到10進制的轉換,這樣返回的就是一個字符串了。
mysql默認會以‘,’來分隔多的值,如果想用其他的分隔符來分隔返回結果,比如期望返回值是這樣的:1|2|3|4
這可以用SEPARATOR來搞定。
- select year,month GROUP_CONCAT(conv( oct( volumn ) , 8, 10 ) SEPARATOR '|') from magazine group by year,month order by year desc, month desc
更牛的是,你甚至可以對返回的volumn進行排序!!
- select year,month GROUP_CONCAT(conv( oct( volumn ) , 8, 10 ) order by volumn desc SEPARATOR '|') from magazine group by year,month order by year desc, month desc
這個不常用的東東,還是比較好用的。
評論
以下內容轉載於:http://www.cnblogs.com/Arlen/archive/2008/04/30/1177648.html
GROUP_CONCAT使用陷阱
1.int字段的連接陷阱
當你用group_concat的時候請注意,連接起來的字段如果是int型,一定要轉換成char再拼起來,
否則在你執行後(ExecuteScalar或者其它任何執行SQL返回結果的方法)返回的將不是一個逗號隔開的串,
而是byte[]。
該問題當你在SQLyog等一些工具中是體現不出來的,所以很難發現。
附Cast,convert的用法:
CAST(expr AS type), CONVERT(expr,type) , CONVERT(expr USING transcoding_name)
CAST() 和CONVERT() 函數可用來獲取一個類型的值,併產生另一個類型的值。
這個類型 可以是以下值其中的一個:
2.長度陷阱
用group_concat連接字段的時候是有長度限制的,並不是有多少連多少。但你可以設置一下。
使用group_concat_max_len系統變量,你可以設置允許的最大長度。
程序中進行這項操作的語法如下,其中 val 是一個無符號整數:
若已經設置了最大長度, 則結果被截至這個最大長度。
在SQLyog中執行 SET GLOBAL group_concat_max_len = 10 後,重新打開SQLyog,設置就會生效。
請注意,這種方式只是臨時的,如要長久的修改,則需要修改mysql的配置節。
到my.cnf的mysqld節點下加上group_concat_max_len =99999……
重啓mysql。