• 子查询


    子查询:一个查询之中嵌套了其他的若干查询。
    分类:
    按子查询出现的位置:
      select后面
        仅仅支持标量子查询
      from后面
        支持表子查询
      where或having后面 重点
        标量子查询
        列子查询
        行子查询
      exists后面(相关子查询)
    按结果集的行列数不同:
      标量子查询(结果集只有一行一列)
      列子查询(结果集只有一列多行)
      行子查询(结果集有一行多列)
      表子查询(结果集一般为多行多列)

    一、where或having后面

    特点:
      a.子查询放在小括号里面
      b.子查询一般放在条件的右侧
      c.标量子查询,一般搭配着单行操作符使用 (> = <等等这种是单行操作符)
      d.列子查询,一般搭配着多行操作符使用(in,any/some,all)

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

    案例1:谁的工资比Abel高?
    select *
    from employees
    where salary(
        select salary
        from employees
        where last_name='Abel'
    );
    案例2:返回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=143
    ) and salary>(
        select salary
        from employees
        where employee_id=143
    );
    案例3:返回公司工资最少的员工的last_name,job_id和salary
    select last_name,job_id,salary
    from employees
    where salary=(
        select min(salary)
        from employees
    );
    案例4:查询最低工资大于50号部门最低工资的部门id和其最低工资
    select min(salary),department_id
    from employees
    group by department_id
    having min(salary)>(
        select min(salary)
        from employees
        where department_id=50
    );
    View Code

    2.列子查询

    案例:返回location_id是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以及salary
    select last_name,employee_id,job_id,salary
    from employees
    where salary<any(
        select distinct salary
        from employees
        where job_id='IT_PROG'
    )and job_id<>'IT_PROG';
    View Code

    3.行子查询

    案例:查询员工编号最小并且工资最高的员工信息
    select *
    from employees
    where (employee_id,salary)=(
        select min(employee_id),max(salary)
        from employees
    );
    View Code

    二、放在select后面

    仅仅支持标量子查询

    案例1:查询每个部门的员工个数
    select d.* ,(
        select count(*)
        from employees e
        where e.department_id=d.department_id
    ) num
    from departments d;
    案例2:查询员工号=102的部门名
    select (
        select department_name
        from departments d
        inner join employees e
        on d.department_id=e.department_id
        where e.employee_id=102
    ) 部门名;
    View Code

    三、放在from后面

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

    案例1:查询每个部门的平均工资的工资等级
    select ag_dep.*,g.grade_level
    from (
        select avg(salary) 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
    View Code

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

    使用的比较少,一般可以用其他语句替代
    exists(完整的查询语句)
    就是查询有没有值,结果:
    1或0

    select exists(select employee_id from employees where salary=300000);
    案例1:查询有员工的部门名
    select department_name
    from departments d
    where exists(
        select *
        from employees e
        where d.department_id=e.department_id
    );
    案例2:查询没有女朋友的男神信息
    select bo.*
    from boys bo
    where not exists(
        select boyfriend_id
        from beauty b
        where bo.id=b.boyfriend_id
    );
    View Code
  • 相关阅读:
    POJ2104 K-th Number Range Tree
    BZOJ 3390: [Usaco2004 Dec]Bad Cowtractors牛的报复(最大生成树)
    BZOJ 3391: [Usaco2004 Dec]Tree Cutting网络破坏(搜索)
    BZOJ 3412: [Usaco2009 Dec]Music Notes乐谱(离线处理)
    BZOJ 3410: [Usaco2009 Dec]Selfish Grazing 自私的食草者(贪心)
    BZOJ 3403: [Usaco2009 Open]Cow Line 直线上的牛(模拟)
    BZOJ 3402: [Usaco2009 Open]Hide and Seek 捉迷藏(最短路)
    BZOJ 3479: [Usaco2014 Mar]Watering the Fields(最小生成树)
    BZOJ 3432: [Usaco2014 Jan]Cross Country Skiing (二分+染色法)
    BZOJ 3299: [USACO2011 Open]Corn Maze玉米迷宫(BFS)
  • 原文地址:https://www.cnblogs.com/xufengnian/p/11870387.html
Copyright © 2020-2023  润新知