---------group by命令用法----------mysql
1.group by命令用法sql
group by的常規用法是配合聚合函數,利用分組信息進行統計,常見的是配合max等聚合函數篩選數據後分析,以及配合having進行篩選後過濾。數據庫
常見的聚合函數以下:ide
假設現有數據庫表以下:表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');
聚合函數max
select max(user_id),grade from user_info group by grade;
#這條sql的含義很明確,將數據按照grade字段分組,查詢每組最大的user_id以及當前組內容。注意,這裏分組條件是grade,查詢的非聚合條件也是grade。這裏不產生衝突。
結果:
having
select max(user_id),grade from user_info group by grade having grade>'A';
#這條sql與上面例子中的基本相同,不事後面跟了having過濾條件。將grade不知足’>A’的過濾掉了。注意,這裏分組條件是grade,查詢的非聚合條件也是grade。這裏不產生衝突。
結果:
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表中提取。
結果:
這條sql的結果就值得討論了,與上述例子不一樣的是,查詢條件多了id一列。數據按照grade分組後,grade一列是相同的,max(user_id)按照數據進行計算也是惟一的,id一列是如何取值的?看上述的數據結果,
推論:id是物理內存的第一個匹配項。
到底是與不是須要繼續探討。
修改數據
修改id按照上述數據結果,將id=1,改成id=99,執行sql後結論:
顯然,與上述例子的結果不一樣。第一條數據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表中提取
結果爲:
將數據user_id改成10999後,
執行
select max(user_id),user_id,id,grade from user_info group by grade;
結果爲:
修改了user_id後,並無改變查詢到的數據條目,所以得出修改惟一鍵並不能影響查詢匹配的條目規則,因此條目規則依然是匹配第一條,即id=1。
當group by 與聚合函數配合使用時,功能爲分組後計算
當group by 與having配合使用時,功能爲分組後過濾
當group by 與聚合函數,同時非聚合字段同時使用時,非聚合字段的取值是第一個匹配到的字段內容,即id小的條目對應的字段內容。