• 6、子查询 、having、(not) exists、表中增加一列并补充数据、删除表中对应的数据-mysql


    子查询

    —————————————————————————————————————————————
    子查询一个查询语句嵌套在另一个查询语句内部的查询,这个特性从MySQL 4.1开始引入。

    SQL 中子查询的使用大大增强了 SELECT 查询的能力,因为很多时候查询需要从 结果集 中获取数据,或者需要从 同一个表 中先计算得出一个数据结果,然后与这个数据结果(可能是某个标量,也可能是某个集合)进行比较。

    一、需求分析与问题解决

    1、实际问题

    在这里插入图片描述
    现有解决方式:

    #方式一:
    SELECT salary
    FROM employees
    WHERE last_name = 'Abel';
    
    SELECT last_name,salary
    FROM employees
    WHERE salary > 11000;
    
    #方式二:自连接
    SELECT e2.last_name,e2.salary
    FROM employees e1,employees e2
    WHERE e1.last_name = 'Abel'
    AND e1.`salary` < e2.`salary`
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    #方式三:子查询
    SELECT last_name,salary
    FROM employees
    WHERE salary > (
    		SELECT salary
    		FROM employees
    		WHERE last_name = 'Abel'
    		);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2、子查询的基本使用
    • 子查询的基本语法结构:
      在这里插入图片描述
    • 子查询(内查询)在主查询之前一次执行完成。
    • 子查询的结果被主查询(外查询)使用 。
    • 注意事项
      • 子查询要包含在括号内
      • 将子查询放在比较条件的右侧
      • 单行操作符对应单行子查询,多行操作符对应多行子查询

    3、子查询的分类
    • 分类方式1:

      我们按 内查询 的结果返回一条还是多条记录,将子查询分为单行子查询多行子查询

      • 单行子查询 也可以包含一行多个列
        在这里插入图片描述

      • 多行子查询
        在这里插入图片描述

    • 分类方式2:

      我们按 内查询是否被执行多次,将子查询划分为 相关(或关联)子查询不相关(或非关联)子查询

      • 子查询从数据表中查询了数据结果,如果这个数据结果只执行一次,然后这个数据结果作为主查询的条件进行执行,那么这样的子查询叫做不相关子查询

      • 同样,如果子查询需要执行多次,即采用循环的方式,先从外部查询开始,每次都传入子查询进行查询,然后再将结果反馈给外部,这种嵌套的执行方式就称为相关子查询


    二、单行子查询

    1、单行比较操作符
    操作符含义
    =equal to
    >greater than
    >=greater than or equal to
    <less than
    <=less than or equal to
    <>not equal to

    2、 代码示例
    • 题目:查询工资大于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);
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    • 题目:返回公司工资最少的员工的last_name,job_id和salary

      SELECT last_name, job_id, salary
      FROM   employees
      WHERE  salary = 
                      (SELECT MIN(salary)
                       FROM   employees);
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
    • 题目:查询与141号或174号员工的manager_id和department_id相同的其他员工的employee_id,manager_id,department_id

      • 实现方式1:不成对比较

        SELECT  employee_id, manager_id, department_id
        FROM    employees
        WHERE   manager_id IN
        		  (SELECT  manager_id
                           FROM    employees
                           WHERE   employee_id IN (174,141))
        AND     department_id IN 
        		  (SELECT  department_id
                           FROM    employees
                           WHERE   employee_id IN (174,141))
        AND	employee_id NOT IN(174,141);
        
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
      • 实现方式2:成对比较

        SELECT	employee_id, manager_id, department_id
        FROM	employees
        WHERE  (manager_id, department_id) IN
                              (SELECT manager_id, department_id
                               FROM   employees
                               WHERE  employee_id IN (141,174))
        AND	employee_id NOT IN (141,174);
        
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8

    3、HAVING 中的子查询
    • 首先执行子查询。
    • 向主查询中的 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);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    4、CASE中的子查询

    在CASE表达式中使用单列子查询:

    题目:显式员工的employee_id,last_name和location。其中,若员工department_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;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    5、 子查询中的空值问题
    SELECT last_name, job_id
    FROM   employees
    WHERE  job_id =
                    (SELECT job_id
                     FROM   employees
                     WHERE  last_name = 'Haas');
    # 语句解释:
    #	因为数据中没有 last_name = 'Haas' 的数据,所以 job_id 为 null, 外层用 job_id = null去查询所以显示为null
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    子查询不返回任何行


    6、 非法使用子查询
    SELECT employee_id, last_name
    FROM   employees
    WHERE  salary =
                    (SELECT   MIN(salary)
                     FROM     employees
                     GROUP BY department_id);
    # 语句解释:
    #	因为子查询语句中 select min(salary) from employees group by department_id 查询出了多条数据
    #	那么 salary 不知道使用哪个去等
    # 怎么改?用多行子查询关键字 in 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    多行子查询使用单行比较符

    三、多行子查询

    • 也称为集合比较子查询
    • 内查询返回多行数据
    • 使用多行比较操作符
    1、多行比较操作符
    操作符含义
    IN等于列表中的任意一个
    ANY需要和单行比较操作符一起使用,和子查询返回的某一个值比较
    ALL需要和单行比较操作符一起使用,和子查询返回的所有值比较
    SOME实际上是ANY的别名,作用相同,一般常使用ANY

    体会 ANY 和 ALL 的区别 @TODO


    2、代码示例
    题目:返回其它 job_id 中比 job_id 为 IT_PROG 部门任一工资低的员工的员工号、姓名、job_id 以及salary
    
    • 1
    SELECT employee_id, last_name, job_id, salary 
    FROM employees
    WHERE salary < ANY 
    	(SELECT salary FROM employees WHERE job_id = 'IT_PROG')
    AND job_id <> 'IT_PROG';
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    题目:返回其它job_id中比job_id为‘IT_PROG’部门所有工资都低的员工的员工号、姓名、job_id以及salary
    
    • 1

    在这里插入图片描述

    题目:查询平均工资最低的部门id
    
    • 1
    #方式1:
    SELECT department_id
    FROM employees
    GROUP BY department_id
    HAVING AVG(salary) = (
    			SELECT MIN(avg_sal)
    			FROM (
    				SELECT AVG(salary) avg_sal
    				FROM employees
    				GROUP BY department_id
    				) dept_avg_sal
    			)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    #方式2:
    SELECT department_id
    FROM employees
    GROUP BY department_id
    HAVING AVG(salary) <= ALL (
    				SELECT AVG(salary) avg_sal
    				FROM employees
    				GROUP BY department_id
    )
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3、空值问题
    SELECT last_name
    FROM employees
    WHERE employee_id NOT IN (
    			SELECT manager_id
    			FROM employees
    			);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述


    四、 相关子查询

    1、相关子查询执行流程

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

    相关子查询按照一行接一行的顺序执行,主查询的每一行都执行一次子查询。
    在这里插入图片描述

    说明:子查询中使用主查询中的列


    2、代码示例
    题目:查询员工中工资大于本部门平均工资的员工的last_name,salary和其department_id
    
    • 1
    • 方式一:相关子查询
      在这里插入图片描述

    • 方式二:在 FROM 中使用子查询

      SELECT last_name,salary,e1.department_id
      FROM employees e1,(SELECT department_id,AVG(salary) dept_avg_sal FROM employees GROUP BY department_id) e2
      WHERE e1.`department_id` = e2.department_id
      AND e2.dept_avg_sal < e1.`salary`;
      
      
      • 1
      • 2
      • 3
      • 4
      • 5

    from型的子查询:子查询是作为from的一部分,子查询要用()引起来,并且要给这个子查询取别名,
    把它当成一张“临时的虚拟的表”来使用。

    • ORDER BY 中使用子查询:

       题目:查询员工的id,salary,按照department_name 排序
      
      • 1
      SELECT employee_id,salary
      FROM employees e
      ORDER BY (
      	  SELECT department_name
      	  FROM departments d
      	  WHERE e.`department_id` = d.`department_id`
      	);
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
       题目:若employees表中employee_id与job_history表中employee_id相同的数目不小于2,
       	  输出这些相同id的员工的employee_id,last_name和其job_id
      
      • 1
      • 2
      SELECT e.employee_id, last_name,e.job_id
      FROM   employees e 
      WHERE  2 <= (SELECT COUNT(*)
                   FROM   job_history 
                   WHERE  employee_id = e.employee_id);
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

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

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

      • 条件返回 FALSE
      • 继续在子查询中查找
    • 如果在子查询中存在满足条件的行:

      • 不在子查询中继续查找
      • 条件返回 TRUE
    • NOT EXISTS关键字表示如果不存在某种条件,则返回TRUE,否则返回FALSE。

       题目:查询公司管理者的employee_id,last_name,job_id,department_id信息
      
      • 1
    • 方式一:

      SELECT employee_id, last_name, job_id, department_id
      FROM   employees e1
      WHERE  EXISTS ( SELECT *
                       FROM   employees e2
                       WHERE  e1.employee_id = e2.manager_id);
      
      • 1
      • 2
      • 3
      • 4
      • 5
    • 方式二:自连接

      SELECT DISTINCT e1.employee_id, e1.last_name, e1.job_id, e1.department_id
      FROM   employees e1 JOIN employees e2
      WHERE e1.employee_id = e2.manager_id;
      
      
      • 1
      • 2
      • 3
      • 4
    • 方式三:

      SELECT employee_id,last_name,job_id,department_id
      FROM employees
      WHERE employee_id IN (
      		     SELECT DISTINCT manager_id
      		     FROM employees
      		     );
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
       题目:查询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;
      	# 方式二:
      	SELECT department_id, department_name
      	FROM departments d
      	WHERE NOT EXISTS (SELECT 'X'
      	                  FROM   employees
      	                  WHERE  department_id = d.department_id);
      	
      	
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13

    4、相关更新
    UPDATE table1 alias1
    SET    column = (SELECT expression
                     FROM   table2 alias2
                     WHERE  alias1.column = alias2.column);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    使用相关子查询依据一个表中的数据更新另一个表的数据。

    题目:在employees中增加一个department_name字段,数据为员工对应的部门名称
    
    • 1
    # 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);
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    5、相关删除
     DELETE FROM table1 alias1
     WHERE column operator (SELECT expression
                            FROM   table2 alias2
                            WHERE  alias1.column = alias2.column);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    使用相关子查询依据一个表中的数据删除另一个表的数据。

    题目:删除表employees中,其与emp_history表皆有的数据
    
    • 1
    DELETE FROM employees e
    WHERE employee_id in  
               (SELECT employee_id
                FROM   emp_history 
                WHERE  employee_id = e.employee_id);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    五、抛一个思考题

    • 问题:谁的工资比Abel的高?

    • 解答:

      #方式1:自连接
      SELECT e2.last_name,e2.salary
      FROM employees e1,employees e2
      WHERE e1.last_name = 'Abel'
      AND e1.`salary` < e2.`salary`
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      #方式2:子查询
      SELECT last_name,salary
      FROM employees
      WHERE salary > (
      		SELECT salary
      		FROM employees
      		WHERE last_name = 'Abel'
      		);
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
    • 问题:以上两种方式有好坏之分吗?

    • 解答自连接方式好!

      题目中可以使用子查询,也可以使用自连接。一般情况建议你使用自连接,因为在许多 DBMS 的处理过程中,对于自连接的处理速度要比子查询快得多。

      可以这样理解:子查询实际上是通过未知表进行查询后的条件判断,而自连接是通过已知的自身数据表进行条件判断,因此在大部分 DBMS 中都对自连接处理进行了优化。


    六、子查询的课后练习

    # 1、查询和 Zlotkey 相同部门的员工姓名和工资
    SELECT last_name, salary 
    FROM employees 
    WHERE department_id IN (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
    FROM employees
    WHERE department_id IN (SELECT DISTINCT department_id FROM employees WHERE last_name LIKE '%u%')
    
    # 5、查询在部门的 location_id 为 1700 的部门工作的员工的员工号
    # 方式一:
    SELECT employee_id
    FROM employees e JOIN departments d ON e.department_id = d.department_id
    WHERE d.location_id = '1700'
    # 方式二:
    SELECT employee_id 
    FROM employees
    WHERE department_id IN (SELECT department_id FROM departments WHERE location_id = '1700')
    
    # 6、查询管理者是 King 的员工姓名和工资
    SELECT last_name,salary
    FROM employees
    WHERE manager_id IN (SELECT employee_id FROM employees WHERE last_name = 'King')
    
    # 7、查询工资最低的员工信息:last_name,salary
    SELECT last_name, salary
    FROM employees
    WHERE salary = (SELECT MIN(salary) FROM employees)
    
    # 8、查询平均工资最低的部门信息
    # 方式一:
    SELECT * FROM departments WHERE department_id = (SELECT department_id
    FROM employees
    GROUP BY department_id 
    HAVING AVG(salary) = (
    SELECT MIN(avg_salary)  
    FROM 
    (SELECT AVG(salary) avg_salary
    FROM employees
    GROUP BY department_id) vi_dept_sal))
    
    # 方式二
    SELECT * FROM departments WHERE department_id = (SELECT department_id
    FROM employees
    GROUP BY department_id 
    HAVING AVG(salary) <= ALL (
    SELECT AVG(salary) avg_salary
    FROM employees
    GROUP BY department_id) )
    
    # 方式三:
    SELECT * FROM departments WHERE department_id = (SELECT department_id
    FROM employees
    GROUP BY department_id 
    HAVING AVG(salary) = (SELECT AVG(salary) avg_salary
    FROM employees
    GROUP BY department_id
    ORDER BY avg_salary ASC
    LIMIT 1))
    
    # 方式四:
    SELECT d.* FROM departments d,(
    SELECT department_id, AVG(salary) avg_sal
    FROM employees
    GROUP BY department_id
    ORDER BY avg_sal ASC
    LIMIT 1) t_dept_avg_sal
    WHERE d.department_id = t_dept_avg_sal.department_id
    
    # 9、查询平均工资最低的部门信息和该部门的平均工资(相关子查询)
    # 方式一:
    SELECT d.* ,(SELECT AVG(salary) FROM employees WHERE department_id = d.department_id) avf_sal
    FROM departments d WHERE department_id = (SELECT department_id
    FROM employees
    GROUP BY department_id 
    HAVING AVG(salary) = (
    SELECT MIN(avg_salary)  
    FROM 
    (SELECT AVG(salary) avg_salary
    FROM employees
    GROUP BY department_id) vi_dept_sal))
    
    # 方式二
    SELECT * ,(SELECT AVG(salary) FROM employees WHERE department_id = d.department_id) avf_sal
    FROM departments d WHERE department_id = (SELECT department_id
    FROM employees
    GROUP BY department_id 
    HAVING AVG(salary) <= ALL (
    SELECT AVG(salary) avg_salary
    FROM employees
    GROUP BY department_id) )
    
    # 方式三:
    SELECT * ,(SELECT AVG(salary) FROM employees WHERE department_id = d.department_id) avf_sal
    FROM departments d WHERE department_id = (SELECT department_id
    FROM employees
    GROUP BY department_id 
    HAVING AVG(salary) = (SELECT AVG(salary) avg_salary
    FROM employees
    GROUP BY department_id
    ORDER BY avg_salary ASC
    LIMIT 1))
    
    # 方式四:
    SELECT d.* ,(SELECT AVG(salary) FROM employees WHERE department_id = d.department_id) avf_sal
    FROM departments d,(
    SELECT department_id, AVG(salary) avg_sal
    FROM employees
    GROUP BY department_id
    ORDER BY avg_sal ASC
    LIMIT 1) t_dept_avg_sal
    WHERE d.department_id = t_dept_avg_sal.department_id
    
    # 10、查询平均工资最高的 job 信息
    # 方式一:
    SELECT * FROM jobs WHERE job_id = (SELECT job_id
    FROM employees
    GROUP BY job_id 
    HAVING AVG(salary) = (
    SELECT MAX(avg_salary)  
    FROM 
    (SELECT AVG(salary) avg_salary
    FROM employees
    GROUP BY job_id) vi_dept_sal))
    
    # 方式二
    SELECT * FROM jobs WHERE job_id = (SELECT job_id
    FROM employees
    GROUP BY job_id 
    HAVING MAX(salary) >= ALL (
    SELECT AVG(salary) avg_salary
    FROM employees
    GROUP BY job_id) )
    
    # 方式三:
    SELECT * FROM jobs WHERE job_id = (SELECT job_id
    FROM employees
    GROUP BY job_id 
    HAVING AVG(salary) = (SELECT AVG(salary) avg_salary
    FROM employees
    GROUP BY job_id
    ORDER BY avg_salary DESC
    LIMIT 1))
    
    # 方式四:
    SELECT d.* FROM jobs d,(
    SELECT job_id, AVG(salary) avg_sal
    FROM employees
    GROUP BY job_id
    ORDER BY avg_sal DESC
    LIMIT 1) t_dept_avg_sal
    WHERE d.job_id = t_dept_avg_sal.job_id  
    
    # 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 DISTINCT e1.employee_id, e1.last_name, e1.job_id, e1.department_id
    FROM   employees e1 JOIN employees e2
    WHERE e1.employee_id = e2.manager_id;
    
    # 方式二:子查询
    SELECT employee_id,last_name,job_id,department_id
    FROM employees
    WHERE employee_id IN (
    		     SELECT DISTINCT manager_id
    		     FROM employees
    		     
    		     );
    # 方式三:
    SELECT employee_id, last_name, job_id, department_id
    FROM   employees e1
    WHERE  EXISTS ( SELECT *
                     FROM   employees e2
                     WHERE  e2.manager_id = 
                            e1.employee_id);
    
    # 13、各个部门中 最高工资中 最低的 那个部门的 最低工资是多少?
    # 方式一:
    SELECT MIN(salary) 
    FROM employees 
    WHERE department_id = (
    SELECT department_id 
    FROM employees
    GROUP BY department_id
    HAVING MAX(salary) = (
    SELECT MIN(max_sal)
    FROM (
    SELECT MAX(salary) max_sal
    FROM employees
    GROUP BY department_id) t_dept_max_sal ))
    
    # 方式二:
    SELECT MIN(salary) 
    FROM employees 
    WHERE department_id = (
    SELECT department_id 
    FROM employees
    GROUP BY department_id
    HAVING MAX(salary) <= ALL (
    SELECT MAX(salary) max_sal
    FROM employees
    GROUP BY department_id ))
    
    # 方式三:
    SELECT MIN(salary) 
    FROM employees 
    WHERE department_id = (
    SELECT department_id 
    FROM employees
    GROUP BY department_id
    HAVING MAX(salary) = (
    SELECT MAX(salary) max_sal
    FROM employees
    GROUP BY department_id
    ORDER BY max_sal
    LIMIT 1))
    
    # 方式四:
    SELECT MIN(salary)
    FROM employees e, (SELECT department_id, MAX(salary) max_sal
    FROM employees
    GROUP BY department_id
    ORDER BY max_sal
    LIMIT 1) t_dept_max_sal
    WHERE t_dept_max_sal.department_id = e.department_id
    
    # 14、查询 平均工资 最高的部门的 manager 的详细信息:last_name, department_id, email, salary
    # 方式一:
    SELECT last_name,department_id,email,salary
    FROM employees 
    WHERE employee_id IN (
    SELECT DISTINCT manager_id
    FROM employees
    WHERE department_id = (
    SELECT department_id 
    FROM employees
    GROUP BY department_id
    HAVING AVG(salary) = (
    SELECT MAX(avg_sal)
    FROM (SELECT AVG(salary) avg_sal
    FROM employees
    GROUP BY department_id ) t_dept_avg_sal)))
    # 方式二:(与上面同思路)
    # 方式三:(与上面同思路)
    # 方式四:(与上面同思路)
    
    # 15、查询部门的部门号,其中不包含 job_id 是 "ST_CLERK" 的部门号
    # 方式一:
    SELECT department_id 
    FROM departments
    WHERE department_id NOT IN (SELECT DISTINCT department_id FROM employees WHERE job_id = 'ST_CLERK')
    
    # 方式二:
    SELECT department_id 
    FROM departments d
    WHERE NOT EXISTS (
    		SELECT * FROM employees e WHERE d.department_id = e.`department_id`
    		AND job_id = 'ST_CLERK'
    )
    # 16、选择所有没有管理者的员工的 last_name
    # 方式一:
    SELECT last_name 
    FROM employees
    WHERE manager_id IS NULL
    
    # 方式二:
    SELECT last_name
    FROM employees emp
    WHERE NOT EXISTS (
    		SELECT * FROM employees mgr 
    		WHERE emp.manager_id = mgr.employee_id
    )
    # 17、查询员工号、姓名、雇用时间、工资,其中员工的管理者为'De Haan'
    # 方式一:
    SELECT employee_id,last_name,hire_date,salary
    FROM employees
    WHERE manager_id IN (
    	SELECT employee_id FROM employees WHERE last_name = 'De Haan'
    )
    
    # 方式二:
    SELECT employee_id,last_name,hire_date,salary
    FROM employees emp
    WHERE EXISTS (
    	SELECT * FROM employees mgr
    	WHERE emp.manager_id = mgr.employee_id
    	AND mgr.last_name = 'De Haan'
    )
    # 18、查询各部门中工资比本部门平均工资高的员工的员工号,姓名和工资(相关查询)
    SELECT last_name,salary,e1.department_id
    FROM employees e1,(SELECT department_id,AVG(salary) dept_avg_sal FROM employees GROUP BY department_id) e2
    WHERE e1.`department_id` = e2.department_id
    AND e2.dept_avg_sal < e1.`salary`;
    
    
    # 19、查询每个部门下的部门人数大于 5 的部门名称(相关查询)
    SELECT department_name
    FROM departments d
    WHERE 5 < (
    	SELECT COUNT(*)
    	FROM employees e 
    	WHERE d.`department_id` = e.`department_id`
    )
    
    
    # 20、查询每个国家下的部门个数大于 2 的国家编号(相关查询)
    
    SELECT country_id 
    FROM locations l
    WHERE 2 < (
    	SELECT COUNT(*)
    	FROM departments d
    	WHERE l.location_id = d.`location_id`
    )
    
    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
  • 相关阅读:
    Explainable-ZSL
    c语言初阶测评
    【C++】特殊类的设计
    Google开源offload友好协议PSP,目前已正式部署到生产中
    SIP通话分析
    Vue路由实例
    [其他]IDEA中Maven项目配置国内源
    使用 PHP 和 MySQL 的投票和投票系统
    SQL Server2022版本 + SSMS安装教程(手把手安装教程)
    【设计模式】01-装饰器模式Decorator
  • 原文地址:https://blog.csdn.net/weixin_45080272/article/details/127938754