MySQL數據庫入門—group by命令用法解析

---------group by命令用法----------mysql


1.group by命令用法
sql

group by的常規用法是配合聚合函數,利用分組信息進行統計,常見的是配合max等聚合函數篩選數據後分析,以及配合having進行篩選後過濾。數據庫


常見的聚合函數以下:ide

2.png

  • 假設現有數據庫表以下:表user_info,id主鍵,user_id惟一鍵函數

CREATE TABLE `user_info` ( spa

    `id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵id', code

    `user_id` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '用戶編號', 排序

    `grade` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '年級', 內存

    `class` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '班級', it

    PRIMARY KEY (`id`),    UNIQUE INDEX `uniq_user_id` (`user_id`)

)

ENGINE=InnoDB

  • 數據

INSERT INTO `user_info` (`id`, `user_id`, `grade`, `class`) VALUES (10, '10230', 'C', 'B');

INSERT INTO `user_info` (`id`, `user_id`, `grade`, `class`) VALUES (9, '10229', 'C', 'a');

INSERT INTO `user_info` (`id`, `user_id`, `grade`, `class`) VALUES (8, '10228', 'B', 'b');

INSERT INTO `user_info` (`id`, `user_id`, `grade`, `class`) VALUES (7, '10227', 'B', 'b');

INSERT INTO `user_info` (`id`, `user_id`, `grade`, `class`) VALUES (6, '10226', 'B', 'a');

INSERT INTO `user_info` (`id`, `user_id`, `grade`, `class`) VALUES (5, '10225', 'B', 'a');

INSERT INTO `user_info` (`id`, `user_id`, `grade`, `class`) VALUES (4, '10224', 'A', 'b');

INSERT INTO `user_info` (`id`, `user_id`, `grade`, `class`) VALUES (3, '10223', 'A', 'b');

INSERT INTO `user_info` (`id`, `user_id`, `grade`, `class`) VALUES (2, '10222', 'A', 'a');

INSERT INTO `user_info` (`id`, `user_id`, `grade`, `class`) VALUES (1, '10221', 'A', 'a');

1.png

  • 聚合函數max

select max(user_id),grade from user_info group by grade;

#這條sql的含義很明確,將數據按照grade字段分組,查詢每組最大的user_id以及當前組內容。注意,這裏分組條件是grade,查詢的非聚合條件也是grade。這裏不產生衝突。

結果:

3.png

  • having

select max(user_id),grade from user_info group by grade  having grade>'A';

#這條sql與上面例子中的基本相同,不事後面跟了having過濾條件。將grade不知足’>A’的過濾掉了。注意,這裏分組條件是grade,查詢的非聚合條件也是grade。這裏不產生衝突。

結果:

4.png

Having與Where的區別

  • where 子句的做用是在對查詢結果進行分組前,將不符合where條件的行去掉,即在分組以前過濾數據,where條件中不能包含聚合函數,使用where條件過濾出特定的行。

  • having 子句的做用是篩選知足條件的組,即在分組以後過濾數據,條件中常常包含聚合函數,使用having 條件過濾出特定的組,也可使用多個分組標準進行分組。


2.group by的很是規用法

select max(user_id),id,grade from user_info group by grade;

#顯示出grade組中數值最大的user_id,顯示id,顯示grade,從user_infon表中提取。

結果:

5.png

這條sql的結果就值得討論了,與上述例子不一樣的是,查詢條件多了id一列。數據按照grade分組後,grade一列是相同的,max(user_id)按照數據進行計算也是惟一的,id一列是如何取值的?看上述的數據結果,

推論:id是物理內存的第一個匹配項。
到底是與不是須要繼續探討。


修改數據

  • 修改id按照上述數據結果,將id=1,改成id=99,執行sql後結論:

6.png

顯然,與上述例子的結果不一樣。第一條數據id變成了99,查出的結果第一條數據的id從1變成了2。代表,id這個非聚合條件字段的取值與數據寫入的時間無關,由於id=1的記錄是先於id=2存在的,修改的數據不過是修改了這條數據的內容。結合mysql的數據存儲理論,因爲id是主鍵,因此數據在檢索是是按照主鍵排序後進行過濾的,所以

推論:id字段的選取是按照mysql存儲的檢索數據匹配的第一條
將id改成1後恢復了原始結果,沒法推翻上述推論。


更改查詢條件:

select max(user_id),user_id,id,grade from user_info group by grade;

#顯示出grade組中數值最大的user_id,顯示user_id,顯示id,顯示grade,從user_infon表中提取

結果爲:

7.png

將數據user_id改成10999後,

執行

select max(user_id),user_id,id,grade from user_info group by grade;

結果爲:

8.png


修改了user_id後,並無改變查詢到的數據條目,所以得出修改惟一鍵並不能影響查詢匹配的條目規則,因此條目規則依然是匹配第一條,即id=1。


結論

  • 當group by 與聚合函數配合使用時,功能爲分組後計算

  • 當group by 與having配合使用時,功能爲分組後過濾

  • 當group by 與聚合函數,同時非聚合字段同時使用時,非聚合字段的取值是第一個匹配到的字段內容,即id小的條目對應的字段內容。

相關文章
相關標籤/搜索