1、前言
mysql
的group by
用于對(duì)查詢的數(shù)據(jù)進(jìn)行分組;此外mysql
提供having
子句對(duì)分組內(nèi)的數(shù)據(jù)進(jìn)行過濾。
mysql
提供了許多select
子句關(guān)鍵字,
它們?cè)谡Z句中的順序如下所示:
子句 | 作用 | 是否必須/何時(shí)使用 |
---|---|---|
select | 查詢要返回的數(shù)據(jù)或者表達(dá)式 | 是 |
from | 指定查詢的表 | 否 |
where | 指定行級(jí)過濾 | 否 |
group by | 分組 | 否/對(duì)數(shù)據(jù)分組時(shí)使用 |
having | 分組過濾 | 否/對(duì)分組后的數(shù)據(jù)過濾使用 |
order by | 返回?cái)?shù)據(jù)時(shí)指定排序規(guī)則 | 否 |
limit | 指定返回?cái)?shù)據(jù)的行數(shù) | 否 |
2、準(zhǔn)備user表
準(zhǔn)備一張user表,其ddl和表數(shù)據(jù)如下所示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
set names utf8mb4; set foreign_key_checks = 0; -- ---------------------------- -- table structure for user -- ---------------------------- drop table if exists ` user `; create table ` user ` ( `id` bigint (20) not null auto_increment comment '主鍵' , ` name ` varchar (255) character set utf8 collate utf8_general_ci not null comment '用戶名' , `nation` varchar (255) character set utf8 collate utf8_general_ci null default null comment '民族' , `age` int (11) null default null comment '年齡' , `height` double null default null comment '身高' , `sex` smallint (6) null default null comment '性別' , primary key (`id`) using btree ) engine = innodb character set = utf8 collate = utf8_general_ci row_format = dynamic ; -- ---------------------------- -- records of user -- ---------------------------- insert into ` user ` values (1, '李子捌' , '漢族' , 18, 180, 1); insert into ` user ` values (2, '張三' , '回族' , 20, 175, 1); insert into ` user ` values (3, '李四' , '維吾爾族' , 45, 168, 0); insert into ` user ` values (4, '王五' , '蒙古族' , 18, 177, 1); insert into ` user ` values (5, '趙六' , '漢族' , 16, 184, 0); insert into ` user ` values (6, '田七' , '維吾爾族' , 27, 192, 1); |
user表中數(shù)據(jù)如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
|
mysql> select * from user ; + ----+--------+----------+------+--------+------+ | id | name | nation | age | height | sex | + ----+--------+----------+------+--------+------+ | 1 | 李子捌 | 漢族 | 18 | 180 | 1 | | 2 | 張三 | 回族 | 20 | 175 | 1 | | 3 | 李四 | 維吾爾族 | 45 | 168 | 0 | | 4 | 王五 | 蒙古族 | 18 | 177 | 1 | | 5 | 趙六 | 漢族 | 16 | 184 | 0 | | 6 | 田七 | 維吾爾族 | 27 | 192 | 1 | + ----+--------+----------+------+--------+------+ 6 rows in set (0.00 sec) |
2.1 group by規(guī)則
使用group by
之前需要先了解group by
使用的相關(guān)規(guī)則
-
group by
子句置于where
之后,order by
子句之前 -
having
子句置于group by 之后,order by子句之前 -
group by
子句中的每個(gè)列都必須是select的檢索列或者有效表達(dá)式,不能使用聚集函數(shù) -
select
中使用的表達(dá)式,在group by子句中必須出現(xiàn),并且不能使用別名 -
group by
分組的數(shù)據(jù)中包含null值,null值被分為一組 -
group by
子句可以嵌套,嵌套的分組在最后分組上匯總
2.2 group by使用
需求:
統(tǒng)計(jì)不同民族的用戶數(shù)
語句:
1
2
3
4
5
6
7
8
9
10
|
mysql> select nation, count (*) from user group by nation; + ----------+----------+ | nation | count (*) | + ----------+----------+ | 漢族 | 2 | | 回族 | 1 | | 維吾爾族 | 2 | | 蒙古族 | 1 | + ----------+----------+ 4 rows in set (0.00 sec) |
group by可以結(jié)合where
一起使用,不過where
不能在group by
之后進(jìn)行過濾,使用where
子句之后,分組的數(shù)據(jù)是where子句過濾后的數(shù)據(jù)集。
1
2
3
4
5
6
7
8
|
mysql> select nation, count (*) as nation_num from user where sex = 0 group by nation; + ----------+------------+ | nation | nation_num | + ----------+------------+ | 維吾爾族 | 1 | | 漢族 | 1 | + ----------+------------+ 2 rows in set (0.00 sec) |
2.3 having使用
對(duì)group by
分組后的數(shù)據(jù)還需要再次過濾,就必須使用having
子句。group by
子句后使用where子句mysql服務(wù)器會(huì)拋出異常
1
2
|
mysql> select nation, count (*) as nation_num from user group by nation where nation = '漢族' ; error 1064 (42000): 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 'where nation = ' 漢族 '' at line 1 |
此時(shí)只需要將上面where子句替換成having子句即可,having
子句支持所有的where
操作符,通俗的說where子句能用的地方只有替換成having
就可以在group by
子句后使用了
1
2
3
4
5
6
7
|
vmysql> select nation, count (*) as nation_num from user group by nation having nation = '漢族' ; + --------+------------+ | nation | nation_num | + --------+------------+ | 漢族 | 2 | + --------+------------+ 1 row in set (0.00 sec) |
2.4 order by與limit
分組后的數(shù)據(jù)需要排序可以使用order by
,order by
子句需要更在having
子句之后。
1
2
3
4
5
6
7
8
9
|
mysql> select nation, count (*) as nation_num from user group by nation having nation != '漢族' order by nation_num desc ; + ----------+------------+ | nation | nation_num | + ----------+------------+ | 維吾爾族 | 2 | | 回族 | 1 | | 蒙古族 | 1 | + ----------+------------+ 3 rows in set (0.00 sec) |
對(duì)于輸出的結(jié)果需要指定返回的行數(shù),可以使用limit
,limit子句在整個(gè)語句的最后。
1
2
3
4
5
6
7
8
|
mysql> select nation, count (*) as nation_num from user group by nation having nation != '漢族' order by nation_num desc limit 2; + ----------+------------+ | nation | nation_num | + ----------+------------+ | 維吾爾族 | 2 | | 回族 | 1 | + ----------+------------+ 2 rows in set (0.00 sec) |
2.5 with rollup
在group by子句中,with rollup
可以實(shí)現(xiàn)在分組統(tǒng)計(jì)數(shù)據(jù)基礎(chǔ)上再進(jìn)行相同的統(tǒng)計(jì)(sum,avg,count…)
比如max():
1
2
3
4
5
6
7
8
9
10
11
|
mysql> select nation, max (height) as nation_num from user group by nation with rollup ; + ----------+------------+ | nation | nation_num | + ----------+------------+ | 回族 | 175 | | 漢族 | 184 | | 維吾爾族 | 192 | | 蒙古族 | 177 | | null | 192 | + ----------+------------+ 5 rows in set (0.00 sec) |
比如avg():
1
2
3
4
5
6
7
8
9
10
11
|
mysql> select nation, avg (height) as nation_num from user group by nation with rollup ; + ----------+--------------------+ | nation | nation_num | + ----------+--------------------+ | 回族 | 175 | | 漢族 | 182 | | 維吾爾族 | 180 | | 蒙古族 | 177 | | null | 179.33333333333334 | + ----------+--------------------+ 5 rows in set (0.00 sec) |
比如count():
1
2
3
4
5
6
7
8
9
10
11
|
mysql> select nation, count (*) as nation_num from user group by nation with rollup ; + ----------+------------+ | nation | nation_num | + ----------+------------+ | 回族 | 1 | | 漢族 | 2 | | 維吾爾族 | 2 | | 蒙古族 | 1 | | null | 6 | + ----------+------------+ 5 rows in set (0.00 sec) |
到此這篇關(guān)于淺談mysql中的group by的文章就介紹到這了,更多相關(guān)mysql中的group by內(nèi)容請(qǐng)搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!
原文鏈接:https://juejin.cn/post/7032079581802201124