表名:testusers,字段記錄如圖,以前create
的直接拿來用,將就一下。(懶即生產力)
一)作用:GROUP BY 語句根據一個或多個列對結果集進行分組。會把值相同放到一個組中,最終查詢出的結果只會顯示組中一條記錄。(字母不好理解沒關係,看下面的例子秒懂)
二)example:
1)基本用法:
根據 sex 字段分組,查詢用戶名、年齡、電話、性別。
這就分組成功了!男的一組 女的一組,還有一組那啥,咳咳,搞不清楚的,但是都只顯示了組中一條記錄,我們的效果不夠明顯,接着看下面的例子。)
SELECT `username`,`age`,`tel`,`sex` FROM testusers GROUP BY `sex`;
2)GROUP BY 語句中的GROUP_CONCAT()
函數
根據sex 字段進行分組並查看username字段和age字段的詳細信息。(這下對基本用法就很好理解了。因爲他默認只顯示了組中一條記錄,如果想看組內所以的用戶信息,就需要用到GROUP_CONCAT()函數。接着往下↓)
SELECT GROUP_CONCAT(username),GROUP_CONCAT(age),sex FROM testusers GROUP BY sex
3)COUNT()
函數:統計記錄總數
根據sex 字段分組,查詢性別和用戶名,年齡的詳細信息並統計各組用戶數量。
(查出來記錄以後自己數?太萌了吧?利用COUNT()函數統計記錄總數。當然細心的兄dei已經發現問題了,爲什麼只有三個男的,COUNT()函數統計出來四個?[難道有兩根?!] ,咳咳,是因爲在COUNT()函數中,寫COUNT(*)會統計我們表中的NULL值,如果不想統計NULL值,請寫COUNT(字段名)。看我們上面的表中,最後一條記錄的username是NULL,所以只有三個男的卻統計出四根diao.呸,統計出四個男生。PS:代碼段中AS xxx=取別名)
SELECT COUNT(*) AS totalUsers, GROUP_CONCAT(username) AS userDetail ,GROUP_CONCAT(age) AS userAge,sex FROM testusers GROUP BY sex;
4)加WHERE
條件
在年齡大於等於18的範圍內,根據sex分組,查詢性別和用戶名、年齡的詳細信息並統計各組用戶數量(就是在上條基礎上加了WHERE
條件,”未滿18歲,禁止觀看!”)
5)聚合函數[‘SUM()求和函數’,’MAX()函數:求最大值’,’MIN()函數:求最小值’,’AVG()函數:求平均值’]。一個例子整合運用(計算每組用戶薪水的各項值)。
SELECT COUNT(*) AS totalUsers,GROUP_CONCAT(username) AS userDetail,sex,SUM(salary) AS sum_salary,MAX(salary) AS max_salary,MAX(salary) AS max_salary,MIN(salary) AS min_salary,AVG(salary) AS avg_salary FROM testusers GROUP BY sex;
6):HAVING
子句:對分組結果進行二次篩選
根據性別分組,查詢性別和用戶名,年齡的詳細信息並統計各組用戶總數,得出結果後進行二次篩選出用戶總數在5人及以上的組。相當於WHERE是一次篩選,HAVING是在二/再次篩選.
SELECT COUNT(*) AS totalUsers,GROUP_CONCAT(age) AS userAge,GROUP_CONCAT(username) AS userDetail,sex FROM testusers GROUP BY sex HAVING totalUsers>=5;
7)WITH ROLLUP
子句:
可以實現在分組統計數據基礎上再進行相同的統計(SUM,AVG,COUNT…)。
也就是說,當我們進行分組操作以後,又想再看總的信息,或者還有其他類似操作,普通GROUP BY語句是不能實現的,就需要用到有 WITH ROLLUP 子句的 GROUP BY語句
再膚淺一點,就是會在記錄末尾添加一條記錄,是上面所有記錄的總和。
SELECT coalesce(sex,"總數"),COUNT(*) AS totalUsers,GROUP_CONCAT(age) AS userAge,GROUP_CONCAT(username) AS userDetail FROM testusers GROUP BY sex WITH ROLLUP;
group by 多個字段:
思考一個問題,GROUP BY X意思是將所有具有相同X字段值的記錄放到一個分組裏,即是以X字段進行分組;那麼GROUP BY X, Y呢,同理,此意思是將所有具有 相同X和Y字段值的記錄放到一個分組裏,換言之,是以X和Y字段進行分組。
group by一般是和聚合函數在一起使用,例如count、sum、avg等,使用group by的兩個要素:
(1)出現在select後面的字段,要麼是聚合函數中的,要麼是group by中的。例如:
SELECT Subject, Semester, Count(*)FROM Subject_SelectionGROUP BY Subject, Semester;
(2)要篩選結果,可以先使用where,再用group by 或者先用group by 再用having。參照如下sql語句執行順序,
(1)創建數據表
create table wangyao_test01 (
a varchar(20),
b varchar(20),
c varchar(20) )
(2)插入數據
insert into wangyao_test01 values(1,'a','甲');
insert into wangyao_test01 values(1,'a','甲');
insert into wangyao_test01 values(1,'a','甲');
insert into wangyao_test01 values(1,'a','甲');
insert into wangyao_test01 values(1,'a','乙');
insert into wangyao_test01 values(1,'b','乙');
insert into wangyao_test01 values(1,'b','乙');
insert into wangyao_test01 values(1,'b','乙');
按照b列進行分組,計算a的數量,顯示count(a)和b |
根據c列進行分組,計算a的數量,顯示count(a)和c select count(a),c |
根據b,c兩列進行分組, select count(a),b,c from wangyao_test01 group by b,c |
根據c,b的順序進行分組 select count(a),b,c from wangyao_test01 group by c,b desc |
1. 如果GROUP BY 的列沒有索引,產生臨時表.
2. 如果GROUP BY時,SELECT的列不止GROUP BY列一個,並且GROUP BY的列不是主鍵 ,產生臨時表.
3. 如果GROUP BY的列有索引,ORDER BY的列沒索引.產生臨時表.
4. 如果GROUP BY的列和ORDER BY的列不一樣,即使都有索引也會產生臨時表.
5. 如果GROUP BY或ORDER BY的列不是來自JOIN語句第一個表.會產生臨時表.
6. 如果DISTINCT 和 ORDER BY的列沒有索引,產生臨時表.
Distinct
基本使用
distinct
一般是用來去除查詢結果中的重複記錄的,而且這個語句在select
、insert
、delete
和update
中只可以在select
中使用,具體的語法如下:
select distinct expression[,expression...] from tables [where conditions];
- 1
這裏的expressions可以是多個字段。本文的所有操作都是針對如下示例表的:
CREATE TABLE `NewTable` (
`id` int(11) NOT NULL AUTO_INCREMENT ,
`name` varchar(30) NULL DEFAULT NULL ,
`country` varchar(50) NULL DEFAULT NULL ,
`province` varchar(30) NULL DEFAULT NULL ,
`city` varchar(30) NULL DEFAULT NULL ,
PRIMARY KEY (`id`)
)ENGINE=InnoDB
;
1.1 只對一列操作
這種操作是最常見和簡單的,如下:
select distinct country from person
- 1
結果如下:
1.2 對多列進行操作
select distinct country, province from person
- 1
結果如下:
從上例中可以發現,當distinct
應用到多個字段的時候,其應用的範圍是其後面的所有字段,而不只是緊挨着它的一個字段,而且distinct
只能放到所有字段的前面,如下語句是錯誤的:
SELECT country, distinct province from person; // 該語句是錯誤的
- 1
拋出錯誤如下:
[Err] 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘DISTINCT province from person’ at line 1
1.3 針對NULL
的處理
從1.1和1.2中都可以看出,distinct
對NULL
是不進行過濾的,即返回的結果中是包含NULL
值的。
1.4 與ALL
不能同時使用
默認情況下,查詢時返回所有的結果,此時使用的就是all
語句,這是與distinct
相對應的,如下:
select all country, province from person
- 1
結果如下:
1.5 與distinctrow
同義
select distinctrow expression[,expression...] from tables [where conditions];
- 1
這個語句與distinct的作用是相同的。
1.6 對*
的處理
*
代表整列,使用distinct對*
操作
sql
select DISTINCT * from person
相當於
select DISTINCT id, `name`, country, province, city from person;