MySQL--进阶七:子查询

#子查询

/*含义:出现在其他语句内部的select语句,称为子查询或内查询

外部的查询语句,称为主查询或外查询

分类:

①按子查询出现的位置:

    select后面:仅仅支持 标量子查询

    from后面:支持 表子查询

      ★☆★where或者having后面:标量子查询(单行)√,列子查询(多行)√,行子查询

    exists后面(相关子查询):表子查询

按结果集的行列数不同:

    标量子查询(结果集只有一行一列)

    列子查询(结果集只有一列多行)

    行子查询(结果集有一行多列)

    表子查询(结果集一般为多行多列)

*/

/*一.where或者having后面----------------------------------------------------------------

1.标量子查询(单行子查询)√

2.列子查询(多行子查询)√

3.行子查询

特点:

①子查询放在小括号内

②子查询一般放在条件右侧

③标量子查询,一般搭配单行操作符使用

> < >= <= = <>

列子查询一般搭配多行操作符使用

IN/NOT IN、ANY/SOME、ALL

④子查询的执行优先于主查询执行

*/

#1、标量子查询

#案例1:谁的工资比Abel高

#①查询abel的工资

SELECT salary FROM `employees`

WHERE last_name='Abel'

#②查询员工的信息,满足salary>①的结果

SELECT * FROM employees

WHERE salary>(

SELECT salary FROM `employees`

WHERE last_name='Abel'

);

#案例2:返回job_id与141号员工相同,salary比143号员工多的员工姓名,job_id和工资

①141号员工的job id

SELECT job_id

FROM employees

WHERE employee_id=141;

②查询143员工的salary

SELECT salary

FROM `employees`

WHERE `employee_id`=143;

③查询员工的姓名,job_id和工资 ,要求job_id=①,并且salary>②

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_name,job_id,salary

#①公司的最低工资

SELECT MIN(salary) FROM `employees`;

②查询last_name,job_id,salary,salary=①

SELECT last_name,job_id,salary

FROM `employees`

WHERE salary=(SELECT MIN(salary) FROM `employees`);

#案例4:查询最低工资大于50号部门的最低工资的部门id和其最低工资

①查询50号部门的最低工资

SELECT MIN(salary) FROM `employees`

WHERE `department_id`=50;

②查询每个部门的最低工资

SELECT MIN(salary),department_id

FROM employees

GROUP BY department_id;

#③筛选②满足min(salary)>①的结果

SELECT MIN(salary),department_id

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的部门中所有员工姓名

#①location_id是1400或1700的部门

SELECT DISTINCT `department_id` FROM `departments`

WHERE `location_id` IN(1400,1700);

#②查询员工姓名,要求部门号是①列表中的某一个

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为‘IT_PROG'部门的最低工资

SELECT salary FROM `employees`

WHERE `job_id`='IT_PROG';

#②求比job_id为‘IT_PROG'部门任一工资低的工种

SELECT last_name,employee_id,`job_id`,`salary`

FROM `employees`

WHERE salary

SELECT salary FROM `employees`

WHERE `job_id`='IT_PROG')

AND job_id<>'IT_PROG';

#案例3:返回其他工种中比job_id为‘IT_PROG'部门所有工资低的员工信息

#①求job_id为‘IT_PROG'部门的最低工资

SELECT last_name,employee_id,`job_id`,`salary`

FROM `employees`

WHERE salary

SELECT salary FROM `employees`

WHERE `job_id`='IT_PROG')

AND job_id<>'IT_PROG';

#3、行子查询(结果集是一行多列或多行多列)[用的相对较少]

#案例:查询员工编号最小并且工资最高的员工信息

#方法一

SELECT MIN(`employee_id`)FROM `employees`;

SELECT MAX(salary) FROM `employees`;

SELECT * FROM `employees`

WHERE `employee_id`=(SELECT MIN(`employee_id`)FROM `employees`)

AND salary=(SELECT MAX(salary) FROM `employees`);

#方法二:行子查询

SELECT * FROM employees

WHERE(employee_id,salary)=(

SELECT MIN(employee_id),MAX(salary)

FROM employees

)

#二.select后面 ------------------------------------------------------------------------

/*

仅支持标量子查询,即单行单列

*/

#案例1:查询每个部门的员工个数

SELECT d.*,(

SELECT COUNT(*)

FROM employees e

WHERE e.department_id=d.`department_id`

)个数

FROM departments d;

#案例2:查询员工号=102的部门名

SELECT `department_name`

FROM `departments`

WHERE `job_id`=102

SELECT (

SELECT `department_name`

FROM `departments` d

INNER JOIN `employees` e

ON e.`department_id`=d.`department_id`

WHERE e.`employee_id`=102

)部门名;

#三.from后面-----------------------------------------------------------------------

/*

将子查询结果充当一张表,要求必须起别名。

*/

#案例:查询每个部门的平均工资的工资等级

#①查询每个部门的平均工资

SELECT AVG(salary),`department_id`

FROM `employees`

GROUP BY  `department_id`;

SELECT * FROM `job_grades`;

#②连接①的结果集和job_grade表,筛选条件平均工资  between lowest_sal and highest_sal

SELECT ag_dep.*,g.grade_level

FROM (

SELECT AVG(salary) AS ag,`department_id`

FROM `employees`

GROUP BY  `department_id`

)AS ag_dep  #必须为这张表起别名

INNER JOIN job_grades g

ON ag_dep.ag BETWEEN lowest_sal AND highest_sal;

#四、exists后面的子查询(相关子查询)

SELECT EXISTS(SELECT `employee_id` FROM `employees`  WHERE salary=300000);

/*

语法:exists(完整查询语句)

结果:1或者0

*/

#案例1:查询有员工的部门名

#先去执行外查询,再某一个字段的值去过滤

SELECT department_name

FROM `departments` d

WHERE EXISTS (

SELECT *

FROM `employees` e

WHERE d.`department_id`=e.`department_id`

);

#也可以用in来写

SELECT department_name

FROM `departments` d

WHERE d.`department_id` IN (

SELECT `department_id`

FROM `employees`

)

#案例2:查询没有女朋友的男神信息

SELECT bo.*

FROM `boys` bo

WHERE bo.id NOT IN (

SELECT boyfriend_id FROM beauty)

#exists

SELECT bo.*

FROM boys bo

WHERE NOT EXISTS(

SELECT boyfriend_id

FROM beauty b

WHERE bo.id=boyfriend_id

);

你可能感兴趣的:(MySQL--进阶七:子查询)