MySQL - 子查询

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

分类

  1. 按位置
    1. select
    2. from
    3. wherehaving
    4. exists
  2. 按结果集
    1. 标量子查询:一行一列
    2. 列子查询:多行一列
    3. 行子查询:一行多列
    4. 表子查询:任意,一般为多行多列

wherehaving后面

支持标量子查询、列子查询和行子查询

特点

  1. 子查询语句放在小括号内
  2. 子查询一般放在条件右侧
  3. 标量子查询一般搭配单行操作符:> < >= <= <>;列子查询一般搭配多行操作符:in any/some all

标量子查询

谁的工资比 Abel 高

逐步分析

一、查询abel的工资

select salary
from employees
where last_name = 'Abel';

二、查询工资大于1结果的员工

select *
from employees
where salary > (
    select salary
    from employees
    where last_name = 'Abel'
);

返回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;

三、结合1和2结果查询

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 min(salary) min
from employees;

二、结合结果1查询

select last_name, job_id, salary
from employees
where salary = (
    select min(salary) min
    from employees
);

查询最低工资大于50号部门最低工资的部门id和其最低工资

逐步分析

一、查询50号部门的最低工资

select min(salary)
from employees
where department_id = 50;

二、结合结果1查询

select department_id, min(salary) min
from employees
group by department_id
having min > (
    select min(salary)
    from employees
    where department_id = 50
);

列子查询

返回location_id是1400或1700的部门中的所有员工姓名

逐步分析

一、查询location_id是1400或1700的部门id

select distinct department_id
from departments
where location_id in (1400, 1700);

二、查询在这些部门id的员工姓名

select last_name
from employees
where department_id in (
    select distinct department_id
    from departments
    where location_id in (1400, 1700)
);

或者使用any关键字

select last_name
from employees
where department_id = any (
    select distinct department_id
    from departments
    where location_id in (1400, 1700)
);

返回其它工种中比job_id为‘IT_PROG’工种任一工资低的员工的员工号、姓名、job_id 以及salary

# 1
select distinct salary
from employees
where job_id = 'IT_PROG';
# 2
select employee_id, last_name, job_id, salary
from employees
where job_id <> 'IT_PROG'
  and salary < any (
    select distinct salary
    from employees
    where job_id = 'IT_PROG'
);

或者使用max关键字代替

select employee_id, last_name, job_id, salary
from employees
where job_id <> 'IT_PROG'
  and salary < (
    select max(salary)
    from employees
    where job_id = 'IT_PROG'
);

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

# 1
select distinct department_id
from employees
where job_id = 'IT_PROG';
# 2
select distinct salary
from employees
where department_id = (
    select distinct department_id
    from employees
    where job_id = 'IT_PROG'
);
# 3
select employee_id, last_name, job_id, salary
from employees
where department_id <> (
    select distinct department_id
    from employees
    where job_id = 'IT_PROG'
)
  and (
        salary < all (select distinct salary
                      from employees
                      where department_id = (
                          select distinct department_id
                          from employees
                          where job_id = 'IT_PROG'
                      ))
    );

行子查询

查询员工编号最小并且工资最高的员工信息

方法一:标量子查询方法

# 1
select min(employee_id)
from employees;
# 2
select max(salary)
from employees;
# 3
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后面

仅支持标量子查询

查询每个部门的员工个数

select d.department_id,
       (
           select count(*)
           from employees e
           where e.department_id = d.department_id
       ) count
from departments d;

查询员工号=102的部门名

select (select department_name from departments d where d.department_id = e.department_id) d_name
from employees e
where e.employee_id = 102;

from后面

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

查询每个部门的平均工资的工资等级

# 1
select department_id, avg(salary) avg
from employees
group by department_id;
# 2
select d.department_id did, d.avg avg, j.grade_level
from (select department_id, avg(salary) avg
      from employees
      group by department_id) d
         left join job_grades j on d.avg between j.lowest_sal and j.highest_sal;

exists后面

语法

select exists(查询语句);

判断结果集是否存在记录

结果为01

查询有员工的部门名

select department_name
from departments d
where exists(
              select * from employees e where e.department_id = d.department_id
          );

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