一、不相容的文法問題。
先看使用如下sql:SELECT count(*),town FROM `players` 結果會報錯。從這裡涉及到sql的一個原則:值的集合與一個行mysql認為是不相容的。這裡,count(*)的結果是一個值。而town列出的結果是很多行,也就是值組成的集合。是以,兩者不不相容的。
而如果加上group by,就不一樣了,如下:
SELECT count(*),town FROM `players` group by sex
上面的sql,并沒有報錯。因為使用了group by子句後,count(*),town所顯示的結果不一樣了。count((*)是根據group by子句的要求進行聚合,結果是值組成的集合。右邊顯示對應的城市(雖然不一定正确和得出子句想要的結果,但文法上通過的)。最後,sql所表示的實際意思是:統計出每個性别所對應多少行。
二、更好地了解group by的内部機制
假如語句是 SELECT sex,name FROM `players` GROUP BY sex
結果如下:
name sex
王滔 "空值"
劉惠 女
王小明 男
假如語句是 SELECT name FROM `players` GROUP BY sex
name
王滔
劉惠
王小明
假如語句是 SELECT sex FROM `players` GROUP BY sex,
結果就是:
sex
"空值"
女
男
了解:group by的原理是将其指定列的值一緻的行歸為一組。那麼,空值也歸為一組。
實質上,使用了group by,上面三個sql語句原理是一樣的,隻是select子句告訴mysql需要的取出的列有不同
SELECT sex FROM `players` GROUP BY sex 與 SELECT sex,name FROM `players` GROUP BY sex沒什麼差別。
因為group by已經指定了操作方式,select需要顯示行的那些列,随時指定。可以了解早就按照group by的要求将所有行就已經分組好了,之後根據需要取每行的哪一列的值了。
通俗了解group by:根據group by指定的列,列值如果相同行劃分到一組中去。
一直認為,使用group by顯示最後的結果應該是下面這樣的:
字段值 a組
字段值 b組
實際情況卻不是這樣
先看測試的一個例子
group by指定一個字段:SELECT * FROM `fanwe_goods` GROUP BY cate_id
大緻結果顯示類似:
cate_id 其他字段....
40 ....
41 ....
46 ....
48 ....
說明,根據類别cate_id進行分組。結果,每個類隻顯示了一行資料。
group by指定多個字段:SELECT * FROM `fanwe_goods` GROUP BY cate_i,city_id
結果是将多行取出來了(整個表的所有行沒有取出)。結果類似:
cate_id city_id
40 16
40 20
41 16
41 20
還有一些行和其他字段的值省略了
看cate_id和city_id的值,都有重複的值。不知道怎麼計算的,取出的結果還是有意外。
結論:
1.group by 後面指定的列不止一個。當我使用如下語句時,也出現了多行的結果(将該組的所有行都列出來了):
SELECT * FROM players GROUP BY sex, town
2.假如group by 後面隻指定了一列,那麼即使一個組有多行值。也不會全部取出,隻取出一個。這樣的情況,是什麼原因?
3.分組後,如果select子句想取出某個字段,那麼它不可能将都屬于a組的記錄都取出來。隻是從a組中取出一個代表性的值出來。不知道原因,大概是:已經按照group by的規則進行分組後,如果想取出所有
資料,mysql變得無所适從。group by隻有在需要進行統計的的時候非常有效。
使用經驗:group by常常跟聚合函數count進行使用,這樣實作按照分組進行統計的效果。比如:需要統計每個地方的商品數量。那麼就按照地方進行分組(同一個地方的先劃到一組中),之後使用統計函數,就
是針對組的成員進行統計了。
進行分組之後的好處,是友善按組别進行統計,并不能實作像上面效果(按組别顯示出所有行)。如果不是需要進行統計,使用group by,我認為就沒有實際意義,因為此時取出的結果比較意外,并不是自己想
要的。也得不到如下結果: