尚硅谷Mysql教程学习笔记 | 第五天 | 子查询
子查询
#进阶7:子查询/*含义:出现在其他语句中的select语句,称为子查询或内查询外部的查询语句,称为主查询或外查询分类:按子查询出现的位置:select 后面:仅仅标量子查询from后面支持表子查询where或having后面:※支持标量子查询√列子查询√行子查询(用的较少)exists后面(相关子查询)表子查询按结果集的行列数不同:标量子查询(结果集只有一行一列)即查出的结果作为标准,列子查询(结果集只有一列多行)行子查询(结果集有一(多)行多列)表子查询(结果集一般为多行多列)*/#一.where 或 having 后面/*1.标量子查询(单行子查询)2.列子查询(多行子查询)3.行子查询(多列多行)特点:子查询都放在小括号内子查询一般放在条件右侧标量子查询,一般搭配单行操作符使用> < >= <= = <>列子查询,一般搭配着多行操作符使用IN、any/some、all子查询的执行优先于主查询的条件,*/#1.标量子查询#案例1:谁的工资比abel高?SELECT last_name,salaryFROM employeesWHERE salary>(SELECT salaryFROM employeesWHERE last_name = 'abel');#案例2:返回job_id与141员工相同,salary比143员工多的员工姓名,job_id和工资SELECT last_name,job_id,salaryFROM employeesWHERE job_id = (SELECT job_idFROM employeesWHERE employee_id = 141)AND salary > (SELECT salaryFROM employeesWHERE employee_id = 143)ORDER BY salary DESC;#案例3:返回公司工资最少的员工的last_name,job_id和salarySELECT last_name,job_id,salaryFROM employeesWHERE salary = (SELECT MIN(salary)FROM employees);#案例4:查询最低工资大于50号部门最低工资的部门id和其最低工资SELECT department_id,MIN(salary)FROM employeesGROUP BY department_idHAVING MIN(salary) > (SELECT MIN(salary)FROM employeesWHERE department_id = 50);#非法使用标量子查询SELECT department_id,MIN(salary)FROM employeesGROUP BY department_idHAVING MIN(salary) > (SELECT salaryFROM employeesWHERE department_id = 50);#2.列子查询(多行子查询)#使用多行比较操作符/*IN/NOT IN 等于列表中的任意一个ANY|SOME 和子查询返回的某一个值比较,跟其中一个比就行ALL 和子查询返回的所有值比较,跟所有比*/#案例1:返回location_id是1400或1700的部门中的所有员工姓名SELECT `last_name`FROM `employees`WHERE `department_id` IN (SELECT `department_id`FROM `departments`WHERE `location_id` IN (1400,1700));SELECT `last_name`FROM `employees`WHERE `department_id` = ANY (SELECT `department_id`FROM `departments`WHERE `location_id` IN (1400,1700));#使用内连接查询SELECT last_nameFROM employees eINNER JOIN departments dWHERE e.`department_id` = d.`department_id`AND d.`location_id` IN (1400,1700);#案例2:返回其他工种中比job_id为‘IT_PROG’部门任一工资低的员工的:工号、姓名、job_id以及salarySELECT employee_id,last_name,job_id,salaryFROM employeesWHERE salary < (SELECT MAX(salary)FROM employeesWHERE job_id = 'IT_PROG')AND job_id <> 'IT_PROG' ;SELECT employee_id,last_name,job_id,salaryFROM employeesWHERE salary < ANY (SELECT DISTINCT salaryFROM employeesWHERE job_id = 'IT_PROG')AND job_id <> 'IT_PROG' ;#案例3:返回其他工种中比job_id为‘IT_PROG’部门所有工资都低的员工的:工号、姓名、job_id以及salarySELECT employee_id,last_name,job_id,salaryFROM employeesWHERE salary < ALL (SELECT DISTINCT salaryFROM employeesWHERE job_id = 'IT_PROG')AND job_id <> 'IT_PROG' ;SELECT employee_id,last_name,job_id,salaryFROM employeesWHERE salary < (SELECT MIN(salary)FROM employeesWHERE job_id = 'IT_PROG')AND job_id <> 'IT_PROG' ;#3、行子查询(结果一行多列、多行多列(较少))#案例:查询员工编号最小并且工资最高的员工信息#用法很像临时组成新的字段SELECT *FROM employeesWHERE (employee_id,salary)=(SELECT MIN(employee_id),MAX(salary)FROM employees);SELECT *FROM employeesWHERE employee_id = (SELECT MIN(employee_id)FROM employees)AND salary = (SELECT MAX(salary)FROM employees);#二、放在select后面#仅仅支持标量子查询#案例1:查询每个部门的员工个数SELECT d.*,(SELECT COUNT(*)FROM employees eWHERE e.`department_id` = d.`department_id`) 个数FROM departments d;#案例2:查询员工号=102的部门名SELECT (SELECT department_nameFROM `departments` dINNER JOIN employees eON d.department_id = e.department_idWHERE e.employee_id = 102) 部门名;#三、from后面#将子查询充当一张表,要求必须起别名#案例:查询每个部门的平均工资的工资等级SELECT ag_dep.*,g.`grade_level`FROM (SELECT AVG(salary) ag,department_idFROM employeesGROUP BY department_id) ag_depINNER JOIN `job_grades` gON ag_dep.ag BETWEEN g.lowest_sal AND g.`highest_sal`;
