持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第11天,点击查看活动详情
前言
上篇我们学习了MySQL中的子查询的概念以及分类。有兴趣的小伙伴可以阅读(# MySQL学习-子查询)。
下面继续学习MySQL子查询中的单行子查询。
单行子查询
单行子查询即子查询中返回一行数据。
单行比较操作符
| 操作符 | 含义 |
|---|---|
| = | euqal to |
| greater than | |
| >= | greater than or euqal to |
| < | less than |
| <= | less than or euqal to |
| <> | not euqal to |
举例一
查询工资大于2号员工工资的员工信息
子查询的编写步骤:
- 从里往外写
- 从外往里写
从里往外写
- 先查询出2号员工的工资。
SELECT salary
FROM employees
WHERE employee_id = 2
- 再查询大于2号工资的员工信息。
SELECT employee_id, name, salary
FROM employees
WHERE salary > (
SELECT salary
FROM employees
WHERE employee_id = 2
);
| employee_id | name | salary |
|---|---|---|
| 1 | xiaoming | 6800.00 |
这样就可以查询出结果。
举例二
返回job_id与2号员工相同,salary比3号员工多的员工姓名,job_id,和工资。
从里往外写
- 先查出2号员工的job_id,再查出3号员工的工资。
SELECT job_id
FROM employees
WHERE employee_id = 2
SELECT salary
FROM employees
WHERE employee_id = 3
- 再查出和2号员工job_id相同的,工资大于3号员工工资的员工信息。
SELECT job_id, name, salary
FROM employees
WHERE job_id = (
SELECT job_id
FROM employees
WHERE employee_id = 2
)
AND salary > (
SELECT salary
FROM employees
WHERE employee_id = 3
);
| job_id | name | salary |
|---|---|---|
| IT | xiaoming | 6800.00 |
这样就可以查出正确结果。
举例三
返回公司工资最少的员工的name,job_id,salary。
从里往外写
- 先查出公司最少的工资是多少?
SELECT MIN(salary)
FROM employees
- 再查询工资是最少工资的员工信息。
SELECT job_id, name, salary
FROM employees
WHERE salary > (
SELECT MIN(salary)
FROM employees
);
| job_id | name | salary |
|---|---|---|
| IT | xiaolan | 3200.00 |
这样就可以查出信息。
举例四
查询与2号员工的manager_id和department_id相同的其他员工的employee_id,manager_id和department_id。
从外往里写
方式一
- 先写需要查询的结果
SELECT employee_id, manager_id, department_id
FROM employees
WHERE manager_id = (
)
AND department_id = (
)
AND employee_id <> 2;
- 然后分别查询manager_id相同的与department_id相同的。
SELECT employee_id, manager_id, department_id
FROM employees
WHERE manager_id = (
SELECT manager_id
FROM employees
WHERE employee_id = 2
)
AND department_id = (
SELECT department_id
FROM employees
WHERE employee_id = 2
)
AND employee_id <> 2;
| employee_id | manager_id | department_id |
|---|---|---|
| 1 | 10 | 1 |
这样就可以查出结果。
方式二
简化子查询中的manager_id与department_id相同的。
SELECT employee_id, manager_id, department_id
FROM employees
WHERE (manager_id, department_id) = (
SELECT manager_id, department_id
FROM employees
WHERE employee_id = 2
)
AND employee_id <> 2;
| employee_id | manager_id | department_id |
|---|---|---|
| 1 | 10 | 1 |
这样也可以查出结果。方式二比方式一的查询效率稍高,但是适用面比较窄,常用的还是方式一。
HAVING中的子查询
- 首先执行子查询。
- 再向主查询中HAVING子句返回结果。
举例五
查询最低工资大于2号部门最低工资的部门id和其最低工资。
SELECT department_id, MIN(salary)
FROM employees
GROUP BY department_id
HAVING MIN(salary) > (
SELECT MIN(salary)
FROM employees
WHERE department_id = 2
);
| department_id | MIN(salary) |
|---|---|
| 1 | 6800.00 |
这样就可以查出结果。
CASE中的子查询
举例六
查询员工的employee_id,name,location。其中,若员工department_id与location_id为18的department_id相同,则location为‘Canada’,其余则为'USA'。
SELECT employee_id, name, (CASE department_id WHEN (
SELECT department_id
FROM employees
WHERE department_id = 18
) THEN 'Canada'
ELSE 'USA' END) "location"
FROM employees
| employee_id | name | location |
|---|---|---|
| 1 | xiaoming | USA |
这样在CASE语句中增加子查询,从而得出结果。
子查询中的空值问题
SELECT job_id, name, salary
FROM employees
WHERE job_id = (
SELECT job_id
FROM employees
WHERE employee_id = 100
);
查询结果为空,这是因为子查询的结果就是空值。所以当子查询结果是空值是,主查询结果也是空值,不会报错。
非法使用子查询
SELECT employee_id, name
FROM employees
WHERE salary = (
SELECT MIN(salary)
FROM employees
GROUP BY department_id
);
运行发现报错,这是因为子查询查出的是多行数据,但是WHERE语句中使用的是=连接,只能连接单行数据,所以这里应该使用多行数据的比较。
今天先学习到这里,明天继续。