• 一文让你彻底理解SQL关联子查询


    员工表的主要信息:

    需求:检索工资大于同职位的平均工资的员工信息。

    直觉的做法

    员工多,而相应的职位(如销售员、经理、部门经理等)少,因此首先想到的思路是对职位分组,这样就能分别得到各个职位的平均工资,再比较每个人的工资和他对应职位的平均工资,大于平均工资则被筛选出来。

    1.首先得到各个职位的平均工资

    代码如下:
    select job,avg(sal) from emp group by job;

    结果如下:

    2.然后利用子查询,对他们进行对比(幻想)

    1 select * from emp where sal >
    2 (select avg(sal) from emp
    3 group by job);
    

    但是子表查询结果是5行,因此这段代码根本无法执行。

    正确的做法是使用关联子查询

    1 select * from emp e where sal > 
    2 (select avg(sal) from emp where job = e.job);
    

    执行逻辑是这样

    第一步

    先执行外层查询,即先执行:
    select * from emp e;

    结果是:

    也就是该表的所有内容。又因为子查询中连接了这个表本身(where job = e.job ),所以将第一条记录转到子查询。

    第二步

    这条进入子查询后,子查询job是CLERK,所以先筛选出所有Job=‘CLERK’的,再对他们取平均。

    相当于执行了:
    select avg(sal) from emp where job='CLERK';

    结果是:

    第三步

    这个结果进入外层查询where和SMITH这个人的sal进行对比,相当于执行了
    select * from emp where sal>1037.5 and job='CLERK';

    结果是:

    循环

    然后就抽出第一次外层查询的第二条(ALLEN):

    继续如上第一、二、三步。

    会重复计算吗?

    每条记录都执行,第二行的ALLEN和第三行的WARD都是SALESMAN(销售人员),那么他们在子查询中会重复计算一次平均工资进行比较。这样会不会设计重复计算?答案是不会,效率并没有降低,SQL已经对此进行过优化。

    总结

    关联子查询(相关子查询),其特性是能够把主查询的值传递给子查询。

    示例:找到员工表中薪水大于本部门平均薪水的员工

    首先想到的思路是:通过子查询查询部门的平均薪水,然后主查询的薪水大于查询出来的平均薪水即可,如下:

    select empno,ename,sal
    from emp
    where sal > (select avg(sal) from emp where deptno =?)
    

    上面的?处应该是每次主查询的部门,比如主查询是查询销售部的数据,那是更销售部的平均薪水进行对比才对啊。

    关联子查询就是解决这个问题的,可以把主查询的deptno传给子查询,那就能够跟本部门平均薪水对比,如下:

    select empno,ename,sal,(select avg(sal) from emp where deptno =e.deptno) as avgsal
    from emp e
    where sal > (select avg(sal) from emp where deptno =e.deptno)
    

    来源于:https://www.cnblogs.com/heenhui2016/p/10574695.html

  • 相关阅读:
    Servlet入门
    序列化
    ConcurrentHashMap红黑树的实现
    ConcurrentHashMap1.7和1.8的源码分析比较
    TCP/IP中的传输层协议TCP、UDP
    Java内存模型和ConcurrentHashMap 1.7源码分析
    JAVA研发面试题
    面试题(Python)
    初识Python
    Python解释器安装与环境变量添加
  • 原文地址:https://www.cnblogs.com/Uni-Hoang/p/13236358.html
Copyright © 2020-2023  润新知