首页 > 其他分享 >第09章_子查询

第09章_子查询

时间:2024-06-15 19:29:44浏览次数:12  
标签:salary employees 09 查询 department WHERE id SELECT

1. 需求分析与问题解决

1.1 实际问题
#查询工资大于Able的工资

#方式1:内连接
SELECT  e1.last_name,e1.salary
FROM employees e1,employees e2
WHERE e1.`salary`>e2.`salary`
AND  e2.`last_name`='Abel';

#方式2:子查询
SELECT  last_name,salary
FROM employees
WHERE  salary>(
               SELECT salary
               FROM employees
               WHERE last_name='Abel'  
               );
1.2 子查询的基本使用
SELECT  last_name,salary
FROM employees
WHERE  salary>(
               SELECT salary
               FROM employees
               WHERE last_name='Abel'  
               );

#2.称谓的规范:外查询(或者主查询),内查询(子查询)               
/*
   子查询在主查询之前一次完成
   子查询的结果被主查询一次使用
   注意:
   子查询要放在括号内
   将子查询放在条件的右侧
   单行函数对应单行的子查询,多行函数对应多行子查询
*/               

 1.3 子查询的分类

#子查询的分类
#角度1:内容查询返回的结果条目数
#单行子查询VS多行子查询
#角度2:
#相关子查询VS不相关子查询
/*

2. 单行子查询 

2.1 单行比较操作符

#单行查询的操作符:> =   != >= <=
#子查询技巧:1.由外往里写 2.由里往外写

2.2 代码示例

题目:查询工资大于149号员工工资的员工的信息

#练习:查询工资大于149号员工的工资
SELECT  employee_id,last_name,salary
FROM  employees
WHERE salary  >(
             SELECT salary
             FROM employees
             WHERE employee_id=149
               );
#题目:返回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号的manager_id和department_id相同的其他员工的employee_id
#方式1:
SELECT employee_id,manager_id,department_id
FROM employees
WHERE manager_id=( 
                  SELECT manager_id
                  FROM employees
                  WHERE employee_id=141 
                  )
  AND  department_id=(SELECT department_id
                  FROM employees
                  WHERE employee_id=141 
                  )
    AND  employee_id!=141;                             
#方式2:了解
SELECT employee_id,manager_id,department_id
FROM employees
WHERE (manager_id,department_id)=(
                 SELECT manager_id,department_id
                  FROM employees
                  WHERE employee_id=141 
 )AND  employee_id!=141;
2.3 HAVING 中的子查询
#题目:查询最低工资大于50号部门最低工资的部门id和其最低工资

SELECT department_id,MIN(salary)
FROM employees
GROUP BY department_id
HAVING MIN(salary)>(
               SELECT MIN(salary)
               FROM employees
               WHERE department_id=50
)
AND department_id!=50;
2.4 CASE中的子查询
#题目:显式员工的employee_id,last_name和location。
#     其中,若员工departhment_id与location_id为1800的department_id相同
#    ,则location为’Canada’,其余则为’USA’
SELECT employee_id,last_name,CASE department_id WHEN (
                                  SELECT department_id
                                  FROM departments
                                 WHERE location_id=1800) THEN 'Canada'
                                 ELSE 'USA' END   "location"
FROM employees;
2.5 子查询中的空值问题
#4.2子查询的空值问题,
SELECT last_name,job_id
FROM employees
WHERE job_id=(
             SELECT job_id
             FROM employees
             WHERE last_name='bna'


);
2.5 非法使用子查询
#2.5 非法使用子查询
 SELECT employee_id, last_name
 FROM   employees
 WHERE  salary =
                (SELECT   MIN(salary)
                 FROM     employees
                 GROUP BY department_id);

3. 多行子查询


#5.1 多行子查询的操作符:IN ANY ALL

 3.1 ANY/ALL 的区别
#题目:返回其它job_id中比job_id为‘IT_PROG’部门任一工资低的员工的
#         员工号、姓名、job_id 以及salar                 
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
#MSQL中聚合函数不能嵌套,将聚合函数变成一个字段
SELECT department_id,AVG(salary)
FROM employees
GROUP BY department_id
HAVING  AVG(salary)=(

	SELECT MIN(avl)
        FROM(
	SELECT AVG(salary) avl
	FROM employees 
	GROUP BY department_id
	) avg_avl

 );

SELECT department_id,AVG(salary)
FROM employees
GROUP BY department_id
HAVING  AVG(salary)<=ALL(

	
	SELECT AVG(salary) avl
	FROM employees 
	GROUP BY department_id
	

 );
3.3 空值问题
# 3.3 空值问
 #要考虑有没有空值,特别注意
 SELECT last_name
 FROM employees
 WHERE employee_id NOT  IN (
            SELECT manager_id
            FROM employees
            WHERE manager_id IS NOT NULL
            );

4. 相关子查询

4.1 相关子查询执行流程

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

4.2 代码示例 
#练习::查询员工中工资大于本部门平均工资的员工
#         的last_name,salary和其department_id 
#方式1:使用相关子查询           
SELECT  e.last_name,e.salary,e.department_id
FROM   employees e 
WHERE  e.salary > (
             SELECT  AVG(salary)
             FROM  employees   d     
               WHERE d.`department_id`=e.department_id
             ) ;           
#方式2:在from中声明子查询
SELECT  e.last_name,e.salary,e.department_id
FROM employees e ,(
         SELECT department_id,AVG(salary) avl
         FROM employees
         GROUP BY department_id        
               )  d
WHERE  e.`salary`> d.avl && e.`department_id`=d.department_id;

#练习:查询员工的id,salary,按照department_name 排序
SELECT employee_id,salary
FROM employees e
ORDER BY ( 
          SELECT department_name
          FROM departments
          WHERE  e.department_id=department_id
           );

在ORDER BY 中使用子查询

练习:查询员工的id,salary,按照department_name 排序
SELECT employee_id,salary
FROM employees e
ORDER BY ( 
          SELECT department_name
          FROM departments
          WHERE  e.department_id=department_id
           );
           

 

#           
/* 除了GROUP by 之外,其他地方都可以声明子查询
 SELECT ..... (存在符合函数)
 FROM .... (LEFT/RIGHT)JOIN ... ON 多表的连接条件
 (LEFT/RIGHT)JOIN ... ON 多表的连接条件
 WHERE 多表的连接条件 AND 过滤条件不包含聚合函数
 GROUP BY ....
 HAVING  过滤条件包含聚合函数
 ORDER BY ....(ASC,DESC)
 LIMIT .....;


#题目:若employees表中employee_id与job_history表中employee_id相同的
#      数目不小于2,输出这些相同
#      id的员工的employee_id,last_name和其job_id
 SELECT  e.employee_id,e.last_name,e.job_id
 FROM employees e
 WHERE  2<=(
           SELECT COUNT(*)
            FROM  job_history d
            WHERE   d.`employee_id`=e.`employee_id`
            );
                

 

4.3 EXISTS 与 NOT EXISTS关键字
#题目:查询公司管理者的employee_id,last_name,job_id,department_id信息         
#方式1:自连接
SELECT e.employee_id,e.last_name,e.job_id,e.department_id
FROM employees e,employees d
WHERE  e.`manager_id`=d.`employee_id`;

#方式2:子查询
SELECT employee_id,last_name,job_id,department_id
FROM employees 
WHERE  employee_id IN(
                  SELECT  DISTINCT manager_id
                  FROM employees
                 ); 
#方式3:使用exists
SELECT employee_id,last_name,job_id,department_id
FROM employees e
WHERE   EXISTS (
                SELECT *
                FROM   employees d
                WHERE  e.`employee_id`=d.`manager_id`
                  );
#题目:查询departments表中,
#       不存在于employees表中的部门的department_id和department_name 
#方式1:
SELECT d.department_id,d.department_name
FROM employees e RIGHT JOIN departments d
ON  e.`department_id`=d.`department_id`
WHERE  e.`department_id` IS NULL;
#方式2:
SELECT department_id,department_name
FROM  departments d
WHERE NOT EXISTS(
                SELECT *
                FROM employees e
                WHERE e.department_id=d.`department_id`
                  );
                                              

 

4.4 相关更新
题目:在employees中增加一个department_name字段,数据为员工对应的部门名称

# 1)
ALTER TABLE employees
ADD(department_name VARCHAR2(14));

# 2)
UPDATE employees e
SET department_name =	(SELECT department_name FROM departments d
WHERE	e.department_id = d.department_id);
4.4 相关删除
题目:删除表employees中,其与emp_history表皆有的数据

DELETE FROM employees e
WHERE employee_id in
(SELECT employee_id
FROM	emp_history
WHERE	employee_id = e.employee_id);

课后练习题

#第09章 子查询练习题1
【题目】
SELECT * FROM employees;
SELECT * FROM  locations;
SELECT * FROM jobs	;
SELECT * FROM countries;
#1.查询和Zlotkey相同部门的员工姓名和工资
    SELECT  employee_id,salary
    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 employee_id,last_name,department_id
     FROM   employees e
     WHERE  last_name LIKE '%u%' && department_id IN (
                                       SELECT department_id
                                       FROM   employees d
                                        WHERE  e.`department_id`=d.`department_id`
                                        
                                                               
                                   );
     
#5.查询在部门的location_id为1700的部门工作的员工的员工号
        SELECT  employee_id
        FROM employees
        WHERE  department_id IN (
                             SELECT department_id
                             FROM departments
                             WHERE  location_id=1700
        
                             );
        
#6.查询管理者是King的员工姓名和工资
   SELECT e.last_name,e.salary
   FROM employees e
   WHERE e.`manager_id`	=(
                     SELECT d.`employee_id`
                     FROM employees d
                     WHERE  e.`manager_id`=d.`employee_id`&& d.`last_name`='King'
                      )    && e.`last_name`!='King';
#7.查询工资最低的员工信息: last_name, salary
           SELECT  last_name,salary
           FROM employees
           WHERE  salary=(
                         SELECT MIN(salary)
                         FROM employees
                       
                          );
                
 #8.查询平均工资最低的部门信息
          SELECT  d.department_id,d.department_name
          FROM    departments d,employees e  
          WHERE   e.`department_id`=d.`department_id` 
          GROUP  BY department_id
          HAVING  AVG(e.`salary`)   =(
                                 SELECT MIN(val)
                                  FROM (
                                 SELECT department_id ,AVG(salary) val
                                 FROM employees
                                 GROUP BY department_id
                                 )  md
                                  )   ;
                                  
    #方法2:
    SELECT  *
    FROM departments
    WHERE department_id=(
    
          SELECT  department_id
          FROM    employees   
          GROUP  BY department_id
          HAVING  AVG(salary)   =(
                                 SELECT MIN(val)
                                  FROM (
                                 SELECT department_id ,AVG(salary) val
                                 FROM employees
                                 GROUP BY department_id
                                 )  md
                                  )            
                        ) ;
  #方式3:
   SELECT  d.*
  FROM  departments d,(
   SELECT  department_id,AVG(salary) val
   FROM  employees
   GROUP BY department_id
   ORDER BY  val ASC
   LIMIT  0,1
       )  md 
   WHERE d.`department_id`=md.department_id;                         
                                  
#9.查询平均工资最低的部门信息和该部门的平均工资(相关子查询)
       SELECT  department_id,AVG(salary)
       FROM  employees
       GROUP BY department_id
       HAVING  AVG(salary)=(
                           SELECT  MIN(val)
                          FROM(
                          SELECT AVG(salary)  val
                          FROM employees 
                          GROUP BY  department_id
                          ) md
                     );
  #方式2:
  SELECT  d.*,(SELECT  AVG(salary) FROM employees WHERE department_id= d.`department_id`)
  FROM  departments d,( 
                      SELECT   department_id,AVG(salary) val
                      FROM     employees
                      GROUP BY department_id
                      ORDER BY  val
                      LIMIT 0,1
                       )md
  WHERE    d.`department_id`=md.department_id  ;             
                     
                     
                     
#10.查询平均工资最高的 job 信息
      SELECT j.*
      FROM  employees e,jobs j
      WHERE  e.`job_id`=j.`job_id`
      GROUP BY job_id
      HAVING  AVG(salary) =(
                          SELECT  MAX(val)
                           FROM(
                           SELECT  AVG(salary) val
                           FROM  employees
                           GROUP BY  job_id
                        ) md
                         
                           );
      
      
#11.查询平均工资高于公司平均工资的部门有哪些?
         SELECT   department_id
         FROM     employees
         WHERE    department_id IS NOT NULL
         GROUP BY department_id
         HAVING   AVG(salary) > (
                                SELECT AVG(salary)
                                FROM employees
                                 );
 #12.查询出公司中所有 manager 的详细信息
     SELECT  e.employee_id,e.last_name
     FROM employees e
     WHERE       EXISTS (
                        SELECT  employee_id
                        FROM  employees d
                        WHERE  e.employee_id=d.manager_id
                         );     
#13.各个部门中 最高工资中最低的那个部门的 最低工资是多少?
       SELECT MIN(salary)
       FROM employees 
       GROUP BY  department_id
       HAVING    MAX(salary)=(
                           SELECT MIN(val)
                           FROM (
                           SELECT  MAX(salary) val
                           FROM  employees
                           GROUP BY department_id
                           ) md
                           );
                         
 #14.查询平均工资最高的部门的 manager 的详细信息: last_name, department_id, email, salary
         SELECT e.last_name, e.department_id,e.email, e.salary
         FROM employees e
         WHERE    EXISTS (
                                SELECT d.employee_id
                                FROM  employees d
                                WHERE e.`manager_id`=d.`employee_id`
                               )
         GROUP BY department_id
         HAVING   AVG(salary)=(
                            SELECT  MAX(val)                            
                            FROM(
                            SELECT  AVG(salary) val
                            FROM employees
                            GROUP BY department_id
                                )md
                            
                           ) 
         ; 
         SELECT e.last_name, e.department_id,e.email, e.salary
         FROM employees e   
       #  where e.`manager_id` is not null                    
         WHERE EXISTS (
                                SELECT employee_id
                                FROM  employees d
                                WHERE e.`manager_id`=d.`employee_id`
                               ) ;                  
                                
    #改正:方式3:
    SELECT  last_name,department_id,email,salary
    FROM  employees
    WHERE  employee_id IN (
                           SELECT DISTINCT e.manager_id
                           FROM  employees e,(
                                           SELECT department_id,AVG(salary) val
                                           FROM employees
                                           GROUP BY department_id
                                           ORDER BY  val DESC
                                           LIMIT 0,1
                                          
                                           )md
                           WHERE  e.`department_id`=md.department_id              
                                                             
                            );                            
                                
                                                
 #15. 查询部门的部门号,其中不包括job_id是"ST_CLERK"的部门号
          SELECT DISTINCT department_id
          FROM 	 employees
          WHERE  department_id NOT IN (
                                SELECT  department_id
                                FROM  employees
                                WHERE  job_id="ST_CLERK"
                                 );
#16. 选择所有没有管理者的员工的last_name
       SELECT last_name
       FROM  employees e
       WHERE  NOT EXISTS(   
                       SELECT *
                       FROM employees d
                       WHERE  e.`manager_id`=d.`employee_id`    
                            );
       
 #17.查询员工号、姓名、雇用时间、工资,其中员工的管理者为 'De Haan'
         SELECT  employee_id,last_name,hire_date,salary
         FROM  employees
         WHERE   manager_id=(
                               SELECT  employee_id
                               FROM 	employees
                               WHERE   last_name='De Haan'
                            );
 #18.查询各部门中工资比本部门平均工资高的员工的员工号, 姓名和工资(相关子查询)
           SELECT  e.employee_id,e.last_name,e.salary
           FROM  employees e
           WHERE  e.salary >  ( 
                                        SELECT  AVG(d.`salary`)
                                        FROM employees d
                                        WHERE   e.`department_id`=d.`department_id`
                                        GROUP BY department_id
                                              );
#19.查询每个部门下的部门人数大于 5 的部门名称(相关子查询)
           SELECT  d.department_name
           FROM  departments d
           WHERE  5 <= (
                          SELECT  COUNT(*)    
                          FROM employees e
                          WHERE  e.`department_id`=d.`department_id`
                        ); 
#20.查询每个国家下的部门个数大于 2 的国家编号(相关子查询)
            SELECT  country_id
            FROM  locations  l
            WHERE  2 < (
                          SELECT  COUNT(*)
                          FROM departments  d
                          WHERE l.`location_id`=d.`location_id`
                         
                           );

标签:salary,employees,09,查询,department,WHERE,id,SELECT
From: https://blog.csdn.net/2401_84526799/article/details/139706668

相关文章

  • 快速提高MySQL查询效率的实用方法
    快速提高MySQL查询效率的实用方法包括以下几个方面,下面将详细列举并解释:使用合适的索引索引可以大大提高查询的速度,允许数据库系统快速定位和访问特定的数据行。在经常用于WHERE子句、JOIN操作和ORDERBY排序的列上创建索引。避免创建过多的索引,因为索引也会占用存储空间......
  • MySQL入门学习-子查询.ANY
        在MySQL数据库中,子查询是指一条查询语句嵌套在另一条查询语句中,可以用来实现复杂的查询逻辑。子查询通常在WHERE子句中使用,用于过滤或比较查询结果。    子查询ANY是指返回子查询结果集中的任意一个值,与其他子查询类型相比,子查询ANY的特点是返回值......
  • Java Web学习笔记55——DQL基本查询
    DQL:DQL英文全称DataQueryLanguage(数据查询语言),用来查询数据库表中的数据。关键字:SELECT。SELECT是最为常见,最为重要的操作。查询在一个系统中,能占据90%的以上。查询也是最为复杂的一个操作。 查询五子句。准备数据: --DQL-基本查询--1.查询指定字......
  • 基于Python+OpenCV的车牌识别停车场管理系统(PyQt界面)【含Python源码 MX_009期】
    简介:        基于Python和OpenCV的车牌识别停车场管理系统是一种利用计算机视觉技术来自动识别停车场进出车辆的系统。该系统通过摄像头捕获车辆图像,并使用OpenCV库中的图像处理和模式识别技术来识别图像中的车牌号码。一旦车牌被成功识别,系统就会将车辆的进出时间和......
  • oracle中如何查询特定日期?
    1.selectlast_day(to_date('20230101','YYYYMMDD'))fromdual; selectlast_day(to_date(V_END_DATE,'YYYYMMDD'))fromdual; --查询任意一天 当月的最后一天2.selectto_char(to_date('20230101','YYYYMMDD')-1,'YYYYM......
  • 代码随想录算法训练营第38天 | 509. 斐波那契数 、70. 爬楼梯 、746. 使用最小花费爬
    理论基础无论大家之前对动态规划学到什么程度,一定要先看我讲的动态规划理论基础。如果没做过动态规划的题目,看我讲的理论基础,会有感觉是不是简单题想复杂了?其实并没有,我讲的理论基础内容,在动规章节所有题目都有运用,所以很重要!如果做过动态规划题目的录友,看我的理论基础就......
  • Superset二次开发之基于GitLab OpenAPI 查询项目的提交记录中修改的文件
    背景:Superset二次开发,在处理版本升级的过程中,需要手动迁移代码,如何在Superset项目众多的文件中,记录修改过的文件,迁移代码时只需重点关注这些文件修改的内容即可,但是针对项目中多次的commit信息,每个commit又涉及不同的文件,如何快速梳理出这些二开工作中修改的文件,是我们......
  • 2022年09月三级
    青少年软件编程(图形化)等级考试试卷(三级)分数:100  题数:38一、单选题(共25题,共50分)1.运行下列程序后,结果为120的是?()A. B. C. D. 试题编号:20220426-jj-011试题类型:单选题标准......
  • P1095 [NOIP2007 普及组] 守望者的逃离
    [NOIP2007普及组]守望者的逃离题目背景NOIP2007普及组T3题目描述恶魔猎手尤迪安野心勃勃,他背叛了暗夜精灵,率领深藏在海底的娜迦族企图叛变。守望者在与尤迪安的交锋中遭遇了围杀,被困在一个荒芜的大岛上。为了杀死守望者,尤迪安开始对这个荒岛施咒,这座岛很快就会沉......
  • MySQL入门学习-聚合和分组.子查询.相关子查询
        在MySQL中,子查询是指在一个查询语句中嵌套另一个查询语句。子查询可以分为相关子查询和非相关子查询两种类型。    相关子查询是指子查询的执行结果依赖于外部查询中的值。在执行相关子查询时,MySQL会先执行外部查询,然后根据外部查询的结果来执行子查询......