## MySQL分組
* group by
> group by語法可以根據給定字段對查詢結果進行分組統計,相同屬性的數據為一個組。通常,在每組中通過聚合函數來可以計算組中最大,最小等。
> 如果group by帶有having,則只有滿足having后面的條件的組才能輸出。
注意: having 必須在group by之后。
* 與分組相關的聚合函數
count() 返回某個字段的值的行數
max() 求最大某字段最大的值
min() 求某字段最小值
avg() 返回某字段平均值
sum() 求某字段總數
group_concat() 將分組的結果拼接成字符串
* group by分組SQL語法
select 字段 from 表名 where where條件 group by 分組條件 having having條件
order by 字段 asc/desc limit offset, row
注意:
1. GROUP BY必須出現在WHERE 之后,ORDER BY 之前。
2. 除聚集計算語句外,SELECT語句中的每個列都必須在GROUP BY中給出
//錯誤,由於name字段沒有寫到group by之后
select count(id),name,sex from user group by sex;
//正確寫法
select count(id),name,sex from user group by sex,name;
備注:
group by 用於根據字段進行分組
having 指定分組的搜索條件,對分組的結果做進一步的處理
limit 顯示查詢出來的數據條數
## 例子
1. 某個員工信息表(staff)結構和數據如下:
id name dept salary edlevel hiredate
1 張三 開發部 2000 3 2009-10-11
2 李四 開發部 2500 3 2009-10-01
3 王五 設計部 2600 5 2010-10-02
4 王六 設計部 2300 4 2010-10-03
5 馬七 設計部 2100 4 2010-10-06
6 趙八 銷售部 3000 5 2010-10-05
7 錢九 銷售部 3100 7 2010-10-07
8 孫十 銷售部 3500 7 2010-10-06
//staff建表語句
create table staff(
id int not null primary key auto_increment,
name varchar(200) not null,
dept varchar(50) not null comment '部門',
salary float(15,2) comment '薪水',
edlevel tinyint not null comment '等級',
hiredate date not null comment '入職時間'
)engine=innodb default charset=utf8;
insert into staff(name,dept,salary,edlevel,hiredate) values('張三','開發部',2000,3,'2009-10-11');
insert into staff(name,dept,salary,edlevel,hiredate) values('李四','開發部',2500,3,'2009-10-01');
insert into staff(name,dept,salary,edlevel,hiredate) values('王五','設計部',2600,5,'2010-10-02');
insert into staff(name,dept,salary,edlevel,hiredate) values('王六','設計部',2300,4,'2010-10-03');
insert into staff(name,dept,salary,edlevel,hiredate) values('馬七','設計部',2100,4,'2010-10-06');
insert into staff(name,dept,salary,edlevel,hiredate) values('趙八','銷售部',3000,5,'2010-10-05');
insert into staff(name,dept,salary,edlevel,hiredate) values('錢九','銷售部',3100,7,'2010-10-07');
insert into staff(name,dept,salary,edlevel,hiredate) values('孫十','銷售部',3500,7,'2010-10-06');
## 聚合函數的簡單使用
1. 求公司總人數
select count(id) from staff;
2. 求公司薪水總支出
select sum(salary) from staff;
3. 求公司最高薪水
select max(salary) from staff;
4. 求公司最低薪水
select min(salary) from staff;
5. 求公司平均薪水
select avg(salary) from staff;
## 分組與聚合函數結合使用例子
例如,統計出各個部門的員工人數
select count(*) from staff group by dept;
* group_concat函數與group by結合使用例子
求: 得到每個部門的員工的名字
select dept,group_concat(name) from staff group by dept;
例如,列出每個部門最高薪水的結果,sql語句如下:
SELECT dept, MAX(SALARY) FROM staff GROUP BY dept
查詢結果如下:
dept MAXIMUM
開發部 2500
設計部 2600
銷售部 3500
2. 查詢每個部門的總薪水數
select dept, sum(salary) as total from staff group by dept;
查詢結果如下:
dept total
開發部 4500
設計部 7000
銷售部 9600
3. 將where字句與group by 子句一起使用
> 注意: 必須在group by之前指定where
例子: 查詢公司2010年之后入職的各個部門每個級別里的最高薪水
SELECT DEPT, EDLEVEL, MAX( SALARY ) AS MAXIMUM
FROM staff
WHERE HIREDATE > '2010-01-01'
GROUP BY DEPT, EDLEVEL;
查詢結果如下:
DEPT EDLEVEL MAXIMUM
設計部 4 2300
設計部 5 2600
銷售部 5 3000
銷售部 7 3500
4. 在GROUP BY子句之后使用HAVING子句
> 可應用限定條件進行分組,以便系統僅對滿足條件的組返回結果。為此,在GROUP BY子句后面包含一個HAVING子句。HAVING子句可包含一個或多個用AND和OR連接的謂詞。
例如:尋找雇員數超過2個的部門的最高和最低薪水:
SELECT DEPT, MAX( salary ) AS MAXIMUM, MIN( salary ) AS MINIMUM
FROM staff
GROUP BY DEPT
HAVING COUNT( * ) >2;
查詢結果如下:
DEPT MAXIMUM MINIMUM
設計部 2600 2100
銷售部 3500 3000
例如:尋找雇員平均工資大於3000的部門的最高和最低薪水:
select max(salary),min(salary),dept from staff group by dept having avg(salary) > 3000;
查詢結果如下:
DEPT MAXIMUM MINIMUM
銷售部 3500 3000
