使用 GROUP BY
子句可以对查询结果进行分组,通常与聚合函数(如 COUNT
、SUM
、AVG
、MAX
、MIN
)一起使用。GROUP BY
子句会将具有相同值的行归为一组,并对每组应用聚合函数。
基本语法
SELECT column1, column2, AGGREGATE_FUNCTION(column3)
FROM table_name
GROUP BY column1, column2;
示例数据库和表结构
假设我们有一个公司数据库,其中有两个表:employees
和 departments
。
-- 创建数据库
CREATE DATABASE company;
-- 选择数据库
USE company;
-- 创建表 departments
CREATE TABLE departments (
dept_id INT AUTO_INCREMENT PRIMARY KEY,
dept_name VARCHAR(100) NOT NULL
);
-- 创建表 employees
CREATE TABLE employees (
emp_id INT AUTO_INCREMENT PRIMARY KEY,
emp_name VARCHAR(100) NOT NULL,
emp_position VARCHAR(100),
emp_salary DECIMAL(10, 2),
hire_date DATE,
dept_id INT,
FOREIGN KEY (dept_id) REFERENCES departments(dept_id)
);
-- 插入示例数据到 departments 表
INSERT INTO departments (dept_name)
VALUES
('HR'),
('Engineering'),
('Marketing');
-- 插入示例数据到 employees 表
INSERT INTO employees (emp_name, emp_position, emp_salary, hire_date, dept_id)
VALUES
('John Doe', 'Manager', 75000.00, '2023-10-01', 1),
('Jane Smith', 'Developer', 60000.00, '2023-09-01', 2),
('Alice Johnson', 'Analyst', 50000.00, '2023-08-01', 1),
('Bob Brown', 'Developer', 70000.00, '2023-07-01', 2),
('Charlie Brown', 'Tester', 55000.00, '2023-11-01', 3);
使用 GROUP BY 的示例
1. 按部门分组并计算每个部门的员工数量
SELECT dept_id, COUNT(*) AS num_employees
FROM employees
GROUP BY dept_id;
结果:
dept_id | num_employees
--------|---------------
1 | 2
2 | 2
3 | 1
2. 按职位分组并计算每个职位的平均薪水
SELECT emp_position, AVG(emp_salary) AS avg_salary
FROM employees
GROUP BY emp_position;
结果:
emp_position | avg_salary
-------------|------------
Analyst | 50000.00
Developer | 65000.00
Manager | 75000.00
Tester | 55000.00
3. 按部门分组并计算每个部门的总薪水
SELECT dept_id, SUM(emp_salary) AS total_salary
FROM employees
GROUP BY dept_id;
结果:
dept_id | total_salary
--------|--------------
1 | 125000.00
2 | 130000.00
3 | 55000.00
使用 GROUP BY 和 HAVING 子句
HAVING
子句用于对分组后的结果进行过滤,与 WHERE
子句类似,但 WHERE
子句是在分组前进行过滤的,而 HAVING
子句是在分组后进行过滤的。
4. 按部门分组并计算每个部门的员工数量,仅显示员工数量大于1的部门
SELECT dept_id, COUNT(*) AS num_employees
FROM employees
GROUP BY dept_id
HAVING COUNT(*) > 1;
结果:
dept_id | num_employees
--------|---------------
1 | 2
2 | 2
5. 按职位分组并计算每个职位的平均薪水,仅显示平均薪水超过60000的职位
SELECT emp_position, AVG(emp_salary) AS avg_salary
FROM employees
GROUP BY emp_position
HAVING AVG(emp_salary) > 60000;
结果:
emp_position | avg_salary
-------------|------------
Developer | 65000.00
Manager | 75000.00
多列分组
6. 按部门和职位分组,计算每组的员工数量
SELECT dept_id, emp_position, COUNT(*) AS num_employees
FROM employees
GROUP BY dept_id, emp_position;
结果:
dept_id | emp_position | num_employees
--------|--------------|---------------
1 | Manager | 1
1 | Analyst | 1
2 | Developer | 2
3 | Tester | 1
结合 JOIN 和 GROUP BY
7. 按部门名称分组,计算每个部门的员工数量
SELECT d.dept_name, COUNT(e.emp_id) AS num_employees
FROM employees e
JOIN departments d ON e.dept_id = d.dept_id
GROUP BY d.dept_name;
结果:
dept_name | num_employees
------------|---------------
HR | 2
Engineering | 2
Marketing | 1
8. 按部门名称分组,计算每个部门的总薪水
SELECT d.dept_name, SUM(e.emp_salary) AS total_salary
FROM employees e
JOIN departments d ON e.dept_id = d.dept_id
GROUP BY d.dept_name;
结果:
dept_name | total_salary
------------|--------------
HR | 125000.00
Engineering | 130000.00
Marketing | 55000.00
小结
通过使用 GROUP BY
子句,您可以对查询结果进行分组,并且可以结合聚合函数来计算各组的数据统计信息。使用 HAVING
子句可以对分组后的结果进行进一步的过滤,GROUP BY
子句也可以与 JOIN
结合使用,以实现更复杂的数据查询和分析。上述示例展示了不同情况下如何使用 GROUP BY
子句进行分组和计算,这在数据分析和报告中非常有用。