0
点赞
收藏
分享

微信扫一扫

第九章 子查询

第九章 子查询

概念:子查询是指一个查询语句嵌套在另一个查询语句内部的查询,  这个特性从MySQL4.1就开始引入

SQL中子查询的使用大大增强了select查询的能力,因为很多时候查询需要从结果集中获取数据,或者需要

从同一个表中先计算得出一个数据结果,然后与这个数据结果进行比较。


子查询的分类:

角度1:从内查询返回的结果的条目数

单行子查询VS多行子查询

角度2:内查询是否被执行多次

相关子查询VS不相关子查询



SELECT last_name,salary

FROM employees

WHERE salary>(SELECT salary

FROM employees

WHERE last_name='Abel');



单行子查询的操作符

操作符

= equal to

> greater than

>= greater than or equal to

< less than

<= less than or equal to

<=> not equal to


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

SELECT last_name,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);


题目:返回公司工资最少的员工的last_name.job_id,salary


SELECT last_name,job_id,salary

FROM employees

WHERE salary=(SELECT MIN(salary) FROM employees);


题目:查询与141号或174号员工的manager_id和department_id相同的其他员工的employee_id,department_id


SELECT employee_id,department_id ,manager_id

FROM employees

WHERE manager_id=(SELECT manager_id FROM employees WHERE employee_id=141 OR employee_id=174 )

AND

department_id=(SELECT department_id FROM employees WHERE employee_id=141 OR employee_id=174)

AND

employee_id<>141 and employee_id<>174;



3.多行子查询

也称为集合比较子查询

内查询返回多行

使用多行比较操作


3.1多行比较操作符

IN 等于列表中的任意一个

ANY 需要和单行比较操作符一起使用,和子查询返回的某一个值比较

ALL 需要和单行比较操作符一起使用,和子查询返回的所有值比较

SOME 实际上是ANY的别名,作用相同,一般使用ANY


举例:

SELECT employee_id,last_name

FROM employees

WHERE salary

IN (SELECT MIN(salary) FROM employees GROUP BY department_id);


例题:返回其它job_id中比job_id为'IT_PROG'部门任一工资低的员工的员工号


SELECT employee_id,last_name,job_id,salary

FROM employees

WHERE job_id<>'IT_PROG'

AND salary <ANY(

SELECT salary

FROM employees

WHERE job_id='IT_PROG'

);


题目:查询平均工资最低的部门id


做了三层子查询

方式1:

SELECT department_id FROM employees

GROUP BY department_id

HAVING AVG(salary) IN

(


SELECT MIN(avg_salary)

FROM

(SELECT AVG(salary) as avg_salary FROM employees GROUP BY department_id) t_dept_avg_sal);


方式2:

SELECT department_id FROM employees

GROUP BY department_id

HAVING AVG(salary)<= ALL

(

SELECT AVG(salary) FROM employees GROUP BY department_id);


题目:查询平均工资最高的部门id

方式1:

SELECT department_id FROM employees

GROUP BY department_id

HAVING AVG(salary) IN


(

SELECT MAX(avg_max_salary)

FROM

(SELECT AVG(salary) as avg_max_salary FROM employees GROUP BY department_id)t_dept_max_sal);


方式2:

SELECT department_id FROM employees

GROUP BY department_id

HAVING AVG(salary)>=ALL(

SELECT AVG(salary) FROM employees GROUP BY department_id);


空值问题:

SELECT last_name

FROM employees

WHERE employee_id NOT IN(

SELECT manager_id FROM employees

)


4.相关子查询

4.1相关子查询的执行流程

如果子查询的执行依赖外部查询,通常情况下都是因为子查询中的表使用到了外部的表,并进行了条件关联,因此每执行一次外部查询,

子查询都要重新计算一次,这样的子查询就称之为关联子查询


相关子查询按照一行接一行的顺序执行,主查询的每一行都执行一次子查询


题目:查询员工中工资大于本部门平均工资的员工的last_name,salary和其department_id


SELECT last_name,salary,department_id FROM employees

WHERE salary >(SELECT AVG(salary) FROM employees )



SELECT last_name,salary,department_id

FROM employees e1

WHERE salary >(

SELECT AVG(salary)

FROM employees e2

WHERE department_id=e1.department_id

);


题目:查询员工的id,salary,按照department_name排序

SELECT employee_id,salary FROM employees  e ORDER BY (

SELECT department_name FROM departments d WHERE d.department_id=e.department_id

) ASC;



结论;

在select 中,除了GROUP BY 和LIMIT之外,其他任何地方都可以用子查询


题目:若employees表中employees与job_history表中employee_id相同的数目

不小于2,输出这些相同id的员工的employee_id,last_name和其job_id


SELECT * FROM job_history;

SELECT employee_id,last_name,job_id

FROM employees e

WHERE 2<=(

          SELECT COUNT(*) FROM job_history j

       WHERE  e.department_id= j.employee_id  )

     

4.3EXISTS与NOT EXISTS 关键字

关联子查询通常也会和EXISTS操作符一起使用,用来检查在子查询中是否存在满足条件的行


如果在子查询中不存在满足条件的行:

条件返回false.


题目:查询公司管理者的employee_id,last_name,job_id,department_id信息


SELECT DISTINCT m.employee_id,m.last_name,m.job_id,m.department_id

FROM employees e JOIN employees m

ON e.manager_id =m.employee_id;





子查询练习:

子查询技巧:(1)从里往外(2)从外往里


1.查询和Zlotkey相同部门员工的姓名和工资

SELECT last_name,salary ,department_id

FROM employees

WHERE department_id =(

                    SELECT department_id

          FROM employees

          WHERE last_name='Zlotkey'

           );

         

2.查询工资比公司平均工资高的员工号,姓名和工资

SELECT employee_id,last_name,salary

FROM employees

WHERE salary>(

             SELECT AVG(salary)

      FROM employees

     

      );

     

3.选择工资大于所有job_id='SA_MAN'的员工的工资的员工的last_name,job_id,salary

SELECT last_name,job_id,salary

FROM employees

WHERE salary >ALL(

              SELECT salary

       FROM employees

       WHERE job_id='SA_MAN'

       );


4.查询和姓名中包含字母U的员工在相同部门的员工的员工号和姓名

SELECT last_name,employee_id

FROM  employees

WHERE department_id IN(

       SELECT DISTINCT department_id

   FROM employees

   WHERE last_name like '%u%'

);

5.查询在部门的location_id为1700的部门工作的员工的员工号

SELECT employee_id,last_name

FROM employees

WHERE department_id IN(

SELECT department_id

FROM departments

WHERE location_id =1700

);

举报

相关推荐

第九章_子查询

第九章 Flask

第九章JDBC

第九章 时间

第九章 顺序容器

0 条评论