进阶7 子查询
含义: 出现在其他语句中的select 语句 ,称为子查询或者内查询
外部的查询语句,称为主查询或者外查询

分类 :
按照查询出现的位置:

select 后面
from 后面    
where 或者 having 后面
exists (相关子查询)

按照结果集的行列数不同:

标量子查询(结果集只有一行一列)
列子查询(结果集只有一列多行)
行子查询(结果集只有一行多列)
表子查询(结果集一般为多行多列)

能放置的位置:
select 后面 :仅仅支持标量子查询

from 后面    :支持表子查询

♥ where 或者 having 后面 :标量子查询 列子查询 行子查询

exists (相关子查询) 表子查询

一 where 或者 having后面

1.标量子查询(单行子查询)
2.列子查询(多行子查询)
3.行子查询(多列多行)

特点: 子查询放在小括号内 子查询一般放在条件的右边 标量子查询,一般搭配着单行操作符使用 例如 > < >= <= = <> 列子查询:一般搭配多行操作符使用 in any/some all

1.标量子查询。

案列:
工资大于 Able的人
SELECT last_name,salary FROM employees WHERE salary>(SELECT salary FROM employees WHERE last_name='Abel')

查询 , 141员工的所在的部门的人数,并且撤销这个部门员工的工资大于143号员工部门的工资的人员名单。
SELECT last_name,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)

查询公司工资最少的员工的姓名和job id和工资
SELECT last_name,job_id,salary from employees WHERE salary=(SELECT MIN(salary) FROM employees)

查询最低工资大于 70(department_id)的部门编号有谁。
SELECT MIN(salary),department_id from employees GROUP BY department_id HAVING MIN(salary)>(SELECT MIN(salary) FROM employees WHERE department_id=70)

列子查询(多行子查询)

集:一列多行
需要搭配多行操作符来使用。

in / not in  等于列表中的任意一个
any | some  和子查询返回的 某一个 进行比较  (任意一个)
all 和子查询返回的所有值比较

案例:

查询location——id是1400或者1700部门中的员工
SELECT last_name FROM employees WHERE department_id IN (SELECT department_id FROM departments WHERE location_id IN (1400,1700) );




返回其他工种比job_id为‘IT_PROG’部门任意低的员工的员工号、姓名 job_id 以及salary

SELECT last_name,employee_id,job_id,salary 
FROM employees
WHERE salary< ANY (

    SELECT DISTINCT salary FROM employees WHERE job_id ='IT_PROG'
   

)AND job_id<>'IT_PROG';



行子查询

(结果集:一行或者多列多行。)

查询编号最小并且工资最高的员工信息
方法一:其他解决方法

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

方法二:行子查询解决方法。

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

二 select后面的子查询

三 from 后面的子查询。

将子查询结果充当一张表,要求必须起别名

案例:查询每个部门的平均工资的工资等级。

#查询每个部门的平均工资的工资等级。
SELECT ag_dep.*,g.grade_level  
FROM (
SELECT AVG(salary) ag,department_id
FROM employees
GROUP BY department_id
) ag_dep
INNER JOIN job_grades g
ON ag_dep.ag BETWEEN  lowest_sal  AND highest_sal;


四 exists后面的子查询(相关子查询)

exists 里面子查询的结果 有没有值 就像布尔 结果就是 1或者0
select exists( select 字段 from 表);

案例:查询员工名和部门名。

#查询员工名和部门名。 
SELECT department_name FROM departments d
WHERE EXISTS (
SELECT *
FROM employees e
WHERE d.department_id=e.department_id
);