7.MYSQL-DQL查询语言学习-子查询

#进阶7:子查询
/*
含义:
出现在其他语句中的SELECT语句,称为子查询或内查询
外部的查询语句,称为主查询或外查询
分类:
按子查询出现的位置:
							SELECT后面:仅仅支持支标量子查询
							FROM后面:支持表子查询
							WHERE或HAVING后面★:标量子查询(单行);列子查询(多行);行子查询
							exists后面(相关子查询):表子查询
按结果集的行列不同:
							标量子查询(结果集只有一行一列)
							列子查询(结果集只有一列多行)
							行子查询(结果含有多行多列)
							表子查询(结果集一般为多行多列							
*/
#一、WHERE或HAVING后面
#1.标量子查询(单行子查询)
#2.列子查询(多行子查询)
#3.行子查询(多列多行)
/*
特点:1.子查询放在小括号内
2.子查询一般放在条件的右侧
3.标量子查询,一般搭配单行操作符使用
> < >= <= = <>
列子查询:一般搭配着多行操作符使用 IN、ANY/SOME、ALL
4.子查询的执行优先于主查询执行,主查询的条件用到了子查询的结果
*/
#1.标量子查询
#案例1:谁的工资比 Abel高
SELECT
	* 
FROM
	employees 
WHERE
	salary > ( SELECT salary FROM employees WHERE last_name = 'Abel' );
#案例2:返回JOB_ID与141号员工相同,salary比143号员工多的员工 姓名,JOB_I和工资
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 );
#案例3:返回公司工资最少的员工的LAST_ANME,JOB_ID和SALARY
SELECT
	last_name,
	job_id,
	salary 
FROM
	employees 
WHERE
	salary = ( SELECT MIN( salary ) FROM employees );
#案例4:查询最低工资大于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 );
#非法使用标量子查询
#2.列子查询(多行子查询)
/*
IN/NOT IN:等于列表中的任意一个
ANY/SOME:和子查询返回某一个值比较
ALL:和子查询返回的所有值比较
*/
#案例1:返回location_id是1400或1700的部门中的所有员工姓名
#方法1:
SELECT
	last_name,
	location_id 
FROM
	employees E
	INNER JOIN departments D ON E.department_id = D.department_id  
WHERE
	location_id IN ( 1400, 1700 );
#方法2
SELECT
	last_name 
FROM
	employees 
WHERE
	department_id IN ( SELECT DISTINCT department_id FROM departments WHERE location_id IN ( 1400, 1700 ) );
#案例2:返回其他部门中比JOB_ID为'IT_PROG'部门任一工资低的员工的工号、姓名、JOB_ID以及SALARY
SELECT
	employee_id,
	last_name,
	job_id,
	salary 
FROM
	employees 
WHERE
	salary< ANY ( SELECT DISTINCT salary FROM employees WHERE job_id = 'IT_PROG' )AND job_id <> 'IT_PROG';
#3.案例3:返回其他部门中比JOB_ID为'IT_PROG'部门所有工资都低的员工的员工号,姓名,job_id以及salary
SELECT
	employee_id,
	last_name,
	job_id,
	salary 
FROM
	employees 
WHERE
	salary < ALL ( SELECT salary FROM employees WHERE job_id = 'IT_PROG' ) 
	AND job_id <> 'IT_PROG';
	
#3.行子查询(结果集一行多列或多行多列)
#案例:查询员工编号最小并且工资最高的员工信息
#方法1:
SELECT
	* 
FROM
	employees 
WHERE
	employee_id = ( SELECT MIN( employee_id ) FROM employees ) 
	AND salary = ( SELECT MAX( salary ) FROM employees );
#方法2:
SELECT
	* 
FROM
	employees 
WHERE
	( employee_id, salary ) = ( SELECT MIN( employee_id ), MAX( salary ) FROM employees );
#二、SELECT后面的子查询(仅仅支持标量子查询)
#案例1:查询每个部门的员工个数
SELECT
	D.*,
	(SELECT COUNT( employee_id ) FROM employees E WHERE E.department_id=D.department_id) 
FROM
	departments D;
#案例2:查询员工号=102的部门名
SELECT
	( SELECT department_name FROM departments D INNER JOIN employees E ON D.department_id = E.department_id WHERE employee_id = 102 ) 部门名;
	
#三:from后面
/*
注意:将子查询结果充当一张表,要求必须取别名
*/
#案例:查询每个部门的平均工资的工资等级
SELECT
	AG_DEP.*,
	GRADE_LEVEL 
FROM
	( SELECT AVG( salary ) AG, department_id FROM employees GROUP BY department_id ) AG_DEP
	INNER JOIN job_grades J ON AG_DEP.AG BETWEEN J.LOWEST_SAL 
	AND J.HIGHEST_SAL;
	
#四、EXISTS后面(相关子查询)
/*
语法:
EXISTS (完整的查询语句)
结果:1或0
*/
SELECT EXISTS(SELECT employee_id FROM employees WHERE salary = 30000);
#案例1:查询有员工的部门名
SELECT
	department_name 
FROM
	departments D
WHERE
	EXISTS ( SELECT * FROM employees E WHERE E.department_id = D.department_id );
#方法2:
SELECT
	department_name 
FROM
	departments D 
WHERE
	D.department_id IN ( SELECT department_id FROM employees )

测试题:

#1.查询和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.查询各个部门中工资比本部门平均工资高的员工的员工号,姓名和工资
SELECT
	employee_id,
	last_name,
	salary 
FROM
	employees 
WHERE
	salary > ( SELECT AVG( salary ) FROM employees ) 
GROUP BY
	department_id;

#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 = 'K_ING' );

#7.查询工资最高的员工的姓名,要求FIRST_NAME和LAST_NAME显示为一列,列名为姓.名
SELECT
	CONCAT( first_name, '.', last_name ) AS '姓.名' 
FROM
	employees 
WHERE
	salary = ( SELECT MAX( salary ) FROM employees );
发布了25 篇原创文章 · 获赞 2 · 访问量 5451

猜你喜欢

转载自blog.csdn.net/qq_41644888/article/details/104811680