mysql group by。 distinct

 

 

表名: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;

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一般是用來去除查詢結果中的重複記錄的,而且這個語句在selectinsertdeleteupdate中只可以在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中都可以看出,distinctNULL是不進行過濾的,即返回的結果中是包含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;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章