子查询

概念:

出现在其他查询里的查询称为子查询或内查询

内部嵌套其他select语句的查询,叫做主查询或外查询

 

分类:

按子查询出现的位置:

select 后面:

仅支持标量子查询

from后面

支持表子查询

where或having后面(★)

标量子查询 ★(也叫单行子查询)

列子查询 ★(也叫多行子查询)

行子查询

exists后面(称为相关子查询)

表子查询

按结果集的行列数不同

标量子查询(结果集只有一行一列)

列子查询(结果集只有一列多行)

行子查询(结果集有多行多列)

表子查询(结果集随意,一般为多行多列)

特点:

在where和having后面

1 子查询放在小括号里

2 子查询放在条件的右侧

3 标量子查询,一般搭配着单行操作符使用(> < >= 一般搭建条件运算符)

4 列子查询 一般搭配着多行操作符使用(IN、ANY/SOME\ALL)

5 子查询的执行优先主查询

where后面的标量子查询

案例1:

查询工资比某位员工工资高的员工 1首先查询Abel的工资

SELECT salary

FROM employees

WHERE last_name = 'Abel';

 

2然后查询员工的信息,满足salary大于1的结果

SELECT *
FROM employees
WHERE salary>(SELECT salary
FROM employees
WHERE last_name = 'Abel'
);

 

案例2

返回job_id与141员工相同,salary比143员工多的员工姓名和工资

步骤:

先查询141员工的job_id

SELECT job_id
FROM employees
WHERE employee_id = 141;

查询143号员工的salary

SELECT salary
FROM employees
WHERE employee_id = 143;

合在一起查询

SELECT job_id,salary
FROM employees
WHERE job_id = (
SELECT job_id
FROM employees
WHERE employee_id = 141
)AND salary>(
SELECT salary
FROM employees
WHERE employee_id = 143
);
案例3:

返回公司工资最少的员工的名字,job_id和salary

1 首先查询工资最少的工资

SELECT MIN(salary)
FROM employees;

 

2 根据最低工资的工资来匹配输出员工的名字,工作和工资得到自己需要的东西

SELECT last_name,job_id,salary
FROM employees
WHERE salary = (
SELECT MIN(salary)
FROM employees
);

having后面的标量子查询

案例1:

查询最低工资大于50号部门最低工资的部门id和其最低工资

 

1 先查询50号部门的最低工资

SELECT MIN(salary)
FROM employees
WHERE department_id = 50

 

2 查询每个部门的最低工资

SELECT MIN(salary)
FROM employees
GROUP BY department_id;

 

3 筛选2中大于1的结果

SELECT MIN(salary),department_id
FROM employees
GROUP BY department_id
HAVING MIN(salary) > (
SELECT MIN(salary)
FROM employees
WHERE department_id = 50
);

 

非法使用标量子查询:

 

单行操作符只能搭建标量子查询

必须对应一行一列,且不能是NULL

多行子查询

返回多行

使用多行比较操作符

操作符含义
IN/NOT IN★ 等于列表中的任意一个
ANY|SOME 和子查询返回的某一个值比较
ALL 和子查询返回的所有值比较

 

案例1

返回location_id是1400或1700部门中的所有员工姓名

1 首先查询location_id是1400或者1700的部门

SELECT department_id
FROM departments
WHERE location_id IN (1400,1700)

2 在1的基础上查询员工的姓名

SELECT last_name
FROM employees
WHERE department_id IN (
SELECT department_id
FROM departments
WHERE location_id IN (1400,1700)
);
案例2

返回其它部门中比job_id为'IT_PROG'部门任一工资低的员工的:工号,姓名,job_id,和salary

1 首先查询job_id为'IT_PROG'的部门信息的员工工资

SELECT DISTINCT salary
FROM employees
WHERE job_id = 'IT_PROG'

2 再any函数来小于任意一个来处理

SELECT last_name
FROM employees
WHERE salary < ANY(
SELECT DISTINCT salary
FROM employees
WHERE job_id = 'IT_PROG'
)AND job_id <>'IT_PROG' ;
案例3

返回其他部门中比job_id为'IT_PROG'部门所有工资都低的员工的工号、姓名、job_id和salary

SELECT employee_id,last_name,job_id,salary
FROM employees
WHERE salary >ALL(
SELECT salary
FROM employees
WHERE job_id = 'IT_PROG'
);

行子查询

结果集为一行多列

案例:

查询员工编号最小并且工资最高的员工信息

方法1:

按照变量子查询来处理:

SELECT MIN(employee_id)
FROM employees
#获取编号最小的员工id

#获得最高工资
SELECT MAX(salary)
FROM employees

#合在一起处理
SELECT *
FROM employees
WHERE employee_id = (
SELECT MIN(employee_id)
FROM employees
)AND salary = (

SELECT MAX(salary)
FROM employees
);

 

方法2:

采用行子查询


SELECT *
FROM employees
WHERE (employee_id,salary) = (
SELECT MIN(employee_id),MAX(salary)
FROM employees
);

select后面的子查询

查询每个部门的员工个数

SELECT d.*,(
SELECT COUNT(*)
FROM employees e
WHERE e.department_id = d.`department_id`
)
FROM departments d;

 

反正嵌套就好了