MySQL 子查询
目录
1. 标量子查询
2. 行子查询
3. 列子查询
4. 表子查询
示例
1. 标量子查询
2. 行子查询
3. 列子查询
4. 表子查询
5. 复杂示例
在 MySQL 中,子查询(或嵌套查询)是指在一个 SQL 查询中嵌套另一个查询。子查询可以用来在主查询中动态地检索数据,常用于过滤、计算和汇总数据等。子查询可以出现在 SELECT
、WHERE
、FROM
和 HAVING
子句中。
1. 标量子查询
- 功能:返回单个值,通常用于
SELECT
或WHERE
子句中。 - 语法:
SELECT 列1, 列2 FROM 表1 WHERE 列1 = (SELECT 列1 FROM 表2 WHERE 条件);
2. 行子查询
- 功能:返回一行多列的结果,通常用于
WHERE
子句中。 - 语法:
SELECT 列1, 列2 FROM 表1 WHERE (列1, 列2) = (SELECT 列1, 列2 FROM 表2 WHERE 条件);
3. 列子查询
- 功能:返回多行单列的结果,通常用于
IN
子句中。 - 语法:
SELECT 列1, 列2 FROM 表1 WHERE 列1 IN (SELECT 列1 FROM 表2 WHERE 条件);
4. 表子查询
- 功能:返回多行多列的结果,通常用于
FROM
子句中。 - 语法:
SELECT t1.列1, t2.列2 FROM 表1 t1 JOIN (SELECT 列1, 列2 FROM 表2 WHERE 条件) t2 ON t1.列1 = t2.列1;
示例
1. 标量子查询
表结构:
employees
表
employee_id | employee_name | salary | department_id |
---|---|---|---|
1 | Alice | 6000 | 1 |
2 | Bob | 5500 | 1 |
3 | Carol | 7000 | 2 |
4 | David | 8000 | 2 |
5 | Eve | 7500 | 3 |
示例:
查找所有员工的姓名,其工资高于公司的平均工资。
SELECT employee_name
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);
2. 行子查询
表结构:
departments
表
department_id | department_name |
---|---|
1 | Sales |
2 | Engineering |
3 | HR |
示例:
查找所有 employees
表中与 departments
表中 "Engineering" 部门的员工相同的员工记录。
SELECT employee_id, employee_name
FROM employees
WHERE (employee_id, department_id) = (
SELECT employee_id, department_id
FROM employees
WHERE department_id = (SELECT department_id FROM departments WHERE department_name = 'Engineering')
);
3. 列子查询
表结构:
managers
表
manager_id | manager_name |
---|---|
1 | Alice |
3 | Carol |
示例:
查找 employees
表中那些员工的 ID 出现在 managers
表中的员工。
SELECT employee_id, employee_name
FROM employees
WHERE employee_id IN (SELECT manager_id FROM managers);
4. 表子查询
表结构:
employees
表(同上)
示例:
查找所有部门的平均工资,并显示每个部门的部门 ID 和其平均工资。
SELECT department_id, avg_salary
FROM (
SELECT department_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id
) AS department_avg_salary;
5. 复杂示例
表结构:
employees
表(同上)
示例:
查找所有工资高于 employees
表中部门 ID 为 2 的所有员工中最高工资的员工。
SELECT employee_id, employee_name, salary
FROM employees
WHERE salary > (
SELECT MAX(salary)
FROM employees
WHERE department_id = 2
);