子查询的使用

一.单行子查询

1.1 单行操作符

子查询的编写技巧  --> 1)  从里往外写  2)  从外往里写

题目:查询工资大于149号员工工资的员工的信息
SELECT last_name,employee_id,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
);
SELECT MIN(salary),last_name
FROM employees
题目:查询与141号员工的manager_id和department_id
相同的其他员工的employee_id, manager_id,department_id
#方式一
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;
#方式二
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;
题目:查询最低工资大于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)
题目:显式员工的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
#子查询中的空值问题(内查询为空)
SELECT last_name, job_id FROM employees WHERE job_id = 
(SELECT job_id FROM employees WHERE last_name = 'Haas');
#非法使用子查询
SELECT employee_id, last_name FROM employees WHERE salary 
= (SELECT MIN(salary) FROM employees GROUP BY department_id); 

二. 多行子查询

内查询返回多行
使用多行比较操作符

2.1 多行比较操作符

 2.2 例子 

题目:返回其它job_id中比job_id为‘IT_PROG’部门任一工资低的员工的员工号、姓名、job_id 以及salary
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' 
)
题目:返回其它job_id中比job_id为‘IT_PROG’部门所有工资都低的员工的员工号、姓名、job_id以及salary
SELECT employee_id,last_name,job_id,salary
FROM employees
WHERE job_id <> 'IT_PROG'
AND salary < ALL (
                     SELECT salary
                      FROM employees
                      WHERE job_id = 'IT_PROG' 
)
题目:查询平均工资最低的部门id
#mysql中聚合函数不能嵌套使用
SELECT department_id
FROM employees
GROUP BY department_id
HAVING AVG(salary) <= ALL (SELECT AVG(salary)
FROM employees
GROUP BY department_id)

2.3 空值问题 

SELECT last_name

FROM employees

WHERE employee_id NOT IN ( SELECT manager_id FROM employees );

内查询有null值

 三. 相关子查询

每次都会执行一次子查询

题目:查询员工中工资大于本部门平均工资的员工的last_name,salary和其department_id
# 方式一
SELECT last_name,salary,department_id 
FROM employees e1
WHERE salary > ( 
                    SELECT AVG(salary)
                    FROM employees
                    WHERE department_id = e1.department_id
                );
 # 方式二 在from 中声明子查询(声明个表)
 SELECT last_name,salary,department_id 
 FROM employees e,(
 SELECT department_id,AVG(salary) avg1
 FROM employees
 GROUP BY department_id) t_dep_avg
 WHERE e.department_id = t_dep_avg.department_id
 AND e.salary > t_dep_avg.avg1
 ####
 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`;
 题目:查询员工的id,salary,按照department_name 排序
 SELECT employee_id,salary FROM employees e ORDER BY 
 ( SELECT department_name FROM departments d WHERE e.`department_id` = d.`department_id` );
 题目:若employees表中employee_id与job_history表中employee_id相同的数目不小于2,输出这些相同
id的员工的employee_id,last_name和其job_id
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); 

结论: 在 select结构中出了group by和limit 中都可以声明子查询 

3.1  EXISTS NOT EXISTS关键字 

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

#方式一
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 e1.employee_id = e2.manager_id

)

题目:查询departments表中,不存在于employees表中的部门的department_id和department_name

SELECT department_id, department_name 
FROM departments d 
WHERE NOT EXISTS (SELECT 'X' 
                  FROM employees 
                  WHERE department_id = d.department_id);

四. 子查询练习 

#查询和Zlotkey相同部门的员工姓名和工资
SELECT last_name,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
FROM employees
WHERE department_id IN (SELECT department_id
                       FROM employees
                       WHERE last_name LIKE '%u%')
#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 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_sal)
			FROM (SELECT AVG(salary) avg_sal
			      FROM employees
			      GROUP BY department_id) t_dep_avg))

#方式二
SELECT *
FROM departments
WHERE department_id = (SELECT department_id
			FROM employees
			GROUP BY department_id
			HAVING AVG(salary) <=  ALL (SELECT AVG(salary)
					      FROM employees
					      GROUP BY department_id
					   ))
#方式三(用limit求出最低平均工资)
SELECT *
FROM departments
WHERE department_id = (SELECT department_id
                       FROM employees
                       GROUP BY department_id
                       HAVING AVG(salary) = (SELECT AVG(salary)
                                             FROM employees
                                             GROUP BY department_id
                                             ORDER BY AVG(salary)
                                             LIMIT 0,1
                                             ))
 #方式四
 SELECT *
 FROM departments d,(SELECT department_id,AVG(salary)
                     FROM employees
                     GROUP BY department_id
                     ORDER BY AVG(salary)
                     LIMIT 0,1) t_dep_avg
 WHERE d.department_id = t_dep_avg.department_id
#9.查询平均工资最低的部门信息和该部门的平均工资(相关子查询)
#方式一
SELECT *
 FROM departments d,(SELECT department_id,AVG(salary)
                     FROM employees
                     GROUP BY department_id
                     ORDER BY AVG(salary)
                     LIMIT 0,1) t_dep_avg
 WHERE d.department_id = t_dep_avg.department_id
#方式二
SELECT d.*,(SELECT AVG(salary) FROM employees WHERE department_id = d.department_id) avg_sal 
FROM departments d 
WHERE department_id = ( 
			SELECT department_id 
			FROM employees 
			GROUP BY department_id 
			HAVING AVG(salary) = ( 
					SELECT MIN(dept_avgsal) 
					FROM (
					SELECT AVG(salary) dept_avgsal 
					FROM employees 
					GROUP BY department_id ) avg_sal ) );
#10.查询平均工资最高的 job 信息(四种写法)
SELECT *
FROM jobs
WHERE  job_id =(SELECT job_id
               FROM employees
               GROUP BY job_id
               HAVING AVG(salary) >= ALL (SELECT AVG(salary)
                                          FROM employees
                                          GROUP BY 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 );
#方式二
SELECT t_dep_avg.department_id
FROM (SELECT department_id,AVG(salary) 'avg1'
FROM employees
GROUP BY department_id) t_dep_avg
WHERE t_dep_avg.avg1>(SELECT AVG(salary)
        FROM employees)
#12.查询出公司中所有 manager 的详细信息
#方式1: 
SELECT  DISTINCT e1.last_name,e1.salary
FROM employees e1 JOIN employees e2
WHERE e1.employee_id = e2.manager_id
#方式二
SELECT employee_id,last_name,salary 
FROM employees 
WHERE employee_id IN ( 
			SELECT DISTINCT manager_id 
			FROM employees );
#方式三
SELECT employee_id, last_name, salary 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) <= ALL( 
					SELECT MAX(salary) max_sal 
					FROM employees 
					GROUP BY department_id ) );



#14.查询平均工资最高的部门的 manager 的详细信息: last_name, department_id, email, salary
#方式一
SELECT last_name, department_id, email, salary
FROM employees
WHERE employee_id IN (SELECT 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_dep_avg

						)
						)
			      )

 #方式二
SELECT last_name, department_id, email, salary
FROM employees
WHERE employee_id IN (SELECT manager_id 
FROM employees
WHERE department_id =(SELECT department_id
			FROM employees
			GROUP BY department_id
			HAVING AVG(salary) >= ALL (
						SELECT AVG(salary) avg_sal
						FROM employees
						GROUP BY department_id
						) 
						)
			      )     
# 方式三
SELECT *
FROM employees
WHERE employee_id IN (

			SELECT manager_id
			FROM employees e,(SELECT department_id
					FROM employees
					GROUP BY department_id
					ORDER BY AVG(salary)
					LIMIT 0,1
					) t_dep_avg
			WHERE e.department_id = t_dep_avg.department_id
			

)

#15. 查询部门的部门号,其中不包括job_id是"ST_CLERK"的部门号
#方式一:
SELECT department_id
FROM employees
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 e.department_id = d.department_id
                  AND  job_id='ST_CLERK')           
#16. 选择所有没有管理者的员工的last_name
SELECT last_name
FROM employees e1
WHERE NOT EXISTS(
                 SELECT *
                 FROM employees mgr
                 WHERE mgr.employee_id = e1.manager_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 e1
WHERE EXISTS (
               SELECT *
               FROM employees mgr
               WHERE e1.manager_id = mgr.employee_id
               AND mgr.last_name='De Haan')
#18.查询各部门中工资比本部门平均工资高的员工的员工号, 姓名和工资(相关子查询)
SELECT employee_id,last_name,salary
FROM employees e1 
WHERE salary > ( 
                # 查询某员工所在部门的平均 
                SELECT AVG(salary) 
                FROM employees e2 
                WHERE e2.department_id = e1.`department_id` );
#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 d.location_id = l.location_id)

#相关子查询,从外往里写






















































































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值