1. 程式人生 > >mysql 的GROUP分組和HAVING二次篩選的使用講解

mysql 的GROUP分組和HAVING二次篩選的使用講解

為了測試GROUP BY 語句,我們建立兩張表,並往表中新增資料

-- 建立部門表 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('教學部'); 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     -> );  

-- 新增省份記錄

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(s

alary) AS '最高薪水',MIN(salary) AS '最低薪水',AVG(salary) AS '平均薪水' FROM employee;

*************************** 1. row ***************************

    編號: 1

  使用者名稱: 張三

員工總數: 9

  總薪水: 62393.14

最高薪水: 9932.14

最低薪水: 4932.92

平均薪水: 6932.571126

1 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 |

+----+------+-----------+