为了测试GROUP BY 语句,我们创建两张表,并往表中添加数据
-- 创建部门表
INSERT employee(username,age,addr,salary,sex,depId) VALUES('李四','32','河北','6432.00','男',2);
INSERT employee(username,age,addr,salary,sex,depId) VALUES('王五','26','北京','5932.92','女',3);
INSERT employee(username,age,addr,salary,sex,depId) VALUES('赵六','32','上海','6232.14','男',4);
INSERT employee(username,age,addr,salary,sex,depId) VALUES('Mr Adword','55','美国','9432.99','男',4);
INSERT employee(username,age,addr,salary,sex,depId) VALUES('田七','19','北京','4932.92','保密',1);
INSERT employee(username,age,addr,salary,sex,depId) VALUES('孙八','62','上海','9932.14','男',2);
INSERT employee(username,age,addr,salary,sex,depId) VALUES('Mr lili','45','美国','9132.99','女',1);
CREATE TABLE IF NOT EXISTS department(
id TINYINT UNSIGNED AUTO_INCREMENT KEY,
depName VARCHAR(20) NOT NULL UNIQUE
);
INSERT department(depName) VALUES('视频部');
INSERT department(depName) VALUES('教学部');
INSERT department(depName) VALUES('运营部');
id Int UNSIGNED AUTO_INCREMENT KEY,
username VARCHAR(20) NOT NULL,
age TINYINT UNSIGNED DEFAULT 18,
addr VARCHAR(50) NOT NULL DEFAULT '北京',
salary FLOAT(6,2) NOT NULL DEFAULT 0,
sex ENUM('男','女','保密'),
depId TINYINT UNSIGNED
);
id TINYINT UNSIGNED AUTO_INCREMENT KEY,
depName VARCHAR(20) NOT NULL UNIQUE
);
-- 添加部门
INSERT department(depName) VALUES('开发部');INSERT department(depName) VALUES('视频部');
INSERT department(depName) VALUES('教学部');
INSERT department(depName) VALUES('运营部');
-- 创建员工表
CREATE TABLE IF NOT EXISTS employee(id Int UNSIGNED AUTO_INCREMENT KEY,
username VARCHAR(20) NOT NULL,
age TINYINT UNSIGNED DEFAULT 18,
addr VARCHAR(50) NOT NULL DEFAULT '北京',
salary FLOAT(6,2) NOT NULL DEFAULT 0,
sex ENUM('男','女','保密'),
depId TINYINT UNSIGNED
);
-- 添加员工记录
INSERT employee(username,age,addr,salary,sex,depId) VALUES('张三','21','山东','5432.12','男',1);INSERT employee(username,age,addr,salary,sex,depId) VALUES('李四','32','河北','6432.00','男',2);
INSERT employee(username,age,addr,salary,sex,depId) VALUES('王五','26','北京','5932.92','女',3);
INSERT employee(username,age,addr,salary,sex,depId) VALUES('赵六','32','上海','6232.14','男',4);
INSERT employee(username,age,addr,salary,sex,depId) VALUES('Mr Adword','55','美国','9432.99','男',4);
INSERT employee(username,age,addr,salary,sex,depId) VALUES('田七','19','北京','4932.92','保密',1);
INSERT employee(username,age,addr,salary,sex,depId) VALUES('孙八','62','上海','9932.14','男',2);
INSERT employee(username,age,addr,salary,sex,depId) VALUES('Mr lili','45','美国','9132.99','女',1);
-- 创建省份表
CREATE TABLE IF NOT EXISTS provinces(
-> id TINYINT UNSIGNED AUTO_INCREMENT KEY,
-> pName VARCHAR(10) NOT NULL UNIQUE
-> );
CREATE TABLE IF NOT EXISTS provinces(
-> id TINYINT UNSIGNED AUTO_INCREMENT KEY,
-> pName VARCHAR(10) NOT NULL UNIQUE
-> );
-- 添加省份记录
INSERT provinces(pName) VALUES('山东'),('河北'),('北京'),('上海'),('美国');mysql> SELECT * FROM department;+----+---------+| id | depName |+----+---------+| 1 | 开发部 || 3 | 教学部 || 2 | 视频部 || 4 | 运营部 |+----+---------+4 rows in set (0.06 sec)mysql> SELECT * FROM employee;+----+-----------+------+------+---------+------+-------+| id | username | age | addr | salary | sex | depId |+----+-----------+------+------+---------+------+-------+| 1 | 张三 | 21 | 山东 | 5432.12 | 男 | 1 || 2 | 李四 | 32 | 河北 | 6432.00 | 男 | 2 || 3 | 王五 | 26 | 北京 | 5932.92 | 女 | 3 || 4 | 赵六 | 32 | 上海 | 6232.14 | 男 | 4 || 5 | 田七 | 19 | 北京 | 4932.92 | 保密 | 1 || 6 | Mr Adword | 55 | 美国 | 9432.99 | 男 | 4 || 7 | 田七 | 19 | 北京 | 4932.92 | 保密 | 1 || 8 | 孙八 | 62 | 上海 | 9932.14 | 男 | 2 || 9 | Mr lili | 45 | 美国 | 9132.99 | 女 | 1 |+----+-----------+------+------+---------+------+-------+
mysql> SELECT * FROM provinces;+----+-------+| id | pName |+----+-------+| 4 | 上海 || 3 | 北京 || 1 | 山东 || 2 | 河北 || 5 | 美国 |+----+-------+
1、只使用GROUP BY语句查询结果只显示每一组的一条记录:
mysql> -- 按照性别分组mysql> SELECT * FROM employee GROUP BY sex;+----+----------+------+------+---------+------+-------+| id | username | age | addr | salary | sex | depId |+----+----------+------+------+---------+------+-------+| 1 | 张三 | 21 | 山东 | 5432.12 | 男 | 1 || 3 | 王五 | 26 | 北京 | 5932.92 | 女 | 3 || 5 | 田七 | 19 | 北京 | 4932.92 | 保密 | 1 |+----+----------+------+------+---------+------+-------+3 rows in set (0.05 sec)mysql> -- 按照部门编号分组mysql> SELECT * FROM employee GROUP BY depId;+----+----------+------+------+---------+------+-------+| id | username | age | addr | salary | sex | depId |+----+----------+------+------+---------+------+-------+| 1 | 张三 | 21 | 山东 | 5432.12 | 男 | 1 || 2 | 李四 | 32 | 河北 | 6432.00 | 男 | 2 || 3 | 王五 | 26 | 北京 | 5932.92 | 女 | 3 || 4 | 赵六 | 32 | 上海 | 6232.14 | 男 | 4 |+----+----------+------+------+---------+------+-------+4 rows in set (0.00 sec)mysql> -- 根据多个字段分组mysql> SELECT * FROM employee GROUP BY sex,depId;+----+----------+------+------+---------+------+-------+| id | username | age | addr | salary | sex | depId |+----+----------+------+------+---------+------+-------+| 1 | 张三 | 21 | 山东 | 5432.12 | 男 | 1 || 2 | 李四 | 32 | 河北 | 6432.00 | 男 | 2 || 4 | 赵六 | 32 | 上海 | 6232.14 | 男 | 4 || 9 | Mr lili | 45 | 美国 | 9132.99 | 女 | 1 || 3 | 王五 | 26 | 北京 | 5932.92 | 女 | 3 || 5 | 田七 | 19 | 北京 | 4932.92 | 保密 | 1 |+----+----------+------+------+---------+------+-------+
2、分组查询配合GROUP_CONCAT()来使用,可以看到每个组中的详细信息:
mysql> -- 按照性别分组,得到每组中人员的名称mysql> SELECT *,GROUP_CONCAT(username) FROM employee GROUP BY sex;+----+----------+------+------+---------+------+-------+-------------------------------+| id | username | age | addr | salary | sex | depId | GROUP_CONCAT(username) |+----+----------+------+------+---------+------+-------+-------------------------------+| 1 | 张三 | 21 | 山东 | 5432.12 | 男 | 1 | 张三,李四,赵六,Mr Adword,孙八 || 3 | 王五 | 26 | 北京 | 5932.92 | 女 | 3 | 王五,Mr lili || 5 | 田七 | 19 | 北京 | 4932.92 | 保密 | 1 | 田七,田七 |+----+----------+------+------+---------+------+-------+-------------------------------+
3、配合聚合函数来使用
- COUNT():统计记录的数目
- SUM():求字段的和
- AVG():求字段的平均值
- MAX():求字段的最大值
- MIN():求字段的最小值
mysql> -- 统计员工表中员工数目,以及薪水的总和、最大值、最小值、平均值mysql> SELECT id AS '编号',username AS '用户名',COUNT(*) AS '员工总数',SUM(salary) AS '总薪水',MAX(salary) AS '最高薪水',MIN(salary) AS '最低薪水',AVG(salary) AS '平均薪水' FROM employee;*************************** 1. row ***************************编号: 1用户名: 张三员工总数: 9总薪水: 62393.14最高薪水: 9932.14最低薪水: 4932.92平均薪水: 6932.5711261 row in set (0.00 sec)
mysql> -- 按照性别分组,统计出每个组中年龄最大值、最小值,薪水最大值,每个组中的人数,人名,以及平均薪水。mysql> SELECT id,sex,MAX(age) AS max_age,MIN(age) AS min_age,MAX(salary) AS max_salary,COUNT(*) AS total_peo,AVG(salary)
AS avg_salary ,GROUP_CONCAT(username)FROM employee GROUP BY sex;
+----+------+---------+---------+------------+-----------+-------------+-------------------------------+
| id | sex | max_age | min_age | max_salary | total_peo | avg_salary | GROUP_CONCAT(username) |
+----+------+---------+---------+------------+-----------+-------------+-------------------------------+
| 1 | 男 | 62 | 21 | 9932.14 | 5 | 7492.278027 | 张三,李四,赵六,Mr Adword,孙八 |
| 3 | 女 | 45 | 26 | 9132.99 | 2 | 7532.955078 | 王五,Mr lili |
| 5 | 保密 | 19 | 19 | 4932.92 | 2 | 4932.919922 | 田七,田七 |
+----+------+---------+---------+------------+-----------+-------------+-------------------------------+
4、使用HAVING 对分组结果进行二次筛选
mysql> -- 按照性别分组,并找到分组后组中人数大于3的组
mysql> SELECT id,sex,COUNT(*) AS total_peo FROM employee GROUP BY sex HAVING COUNT(*)>3;+----+------+-----------+| id | sex | total_peo |+----+------+-----------+| 1 | 男 | 5 |+----+------+-----------+