• 你真的会玩SQL吗?无处不在的子查询


    子查询又称内部,而包含子查询的语句称之外部查询(又称主查询)。 
    所有的子查询可以分为两类,即相关子查询和非相关子查询 
    1>非相关子查询是独立于外部查询的子查询,子查询总共执行一次,执行完毕后将值传递给外部查询。 
    2>相关子查询的执行依赖于外部查询的数据,外部查询执行一行,子查询就执行一次。 
    故非相关子查询比相关子查询效率高 

    --非相关子查询 
    SELECT EMPNO, LASTNAME 
        FROM EMPLOYEE 
        WHERE WORKDEPT = 'A00' 
         AND SALARY > (SELECT AVG(SALARY) 
                  FROM EMPLOYEE 
                  WHERE WORKDEPT = 'A00') 

    --相关子查询 
    SELECT E1.EMPNO, E1.LASTNAME, E1.WORKDEPT 
        FROM EMPLOYEE E1 
        WHERE SALARY > (SELECT AVG(SALARY) 
                  FROM EMPLOYEE E2 
                  WHERE E2.WORKDEPT = E1.WORKDEPT
        ORDER BY E1.WORKDEPT 
     

     子查询

     

    嵌套子查询,非相关子查询   

    相关例子 相关子查询和嵌套子查询 [SQL Server]

    相关子查询

     

    自联接

    联合查询

    •Union 操作符:将两个或更多个 SELECT 语句的结果合并为一个结果集。
    •联合可以指定为如下形式:

         SELECT 语句    UNION [ALL]           SELECT 语句

    使用 ALL 子句表示不删除重复的行

     联合查询注意事项:

    1. 每个select必须具有相同的列结构
    2. 兼容列类型(指优先级较低数据类型必须能隐式地转换为较高级的数据类型)和相同数目的列

    练习:

    使用子查询

    复制代码
    /*1:写一条查询语句,返回Orders表中活动的最后一天生成的所有订单。
    涉及的表:Sales.Orders表。
    期望的输出:*/
    orderid     orderdate               custid      empid
    ----------- ----------------------- ----------- -----------
    11077       2008-05-06 00:00:00.000 65          1
    11076       2008-05-06 00:00:00.000 9           4
    11075       2008-05-06 00:00:00.000 68          8
    11074       2008-05-06 00:00:00.000 73          7
    复制代码

    参考SQL:

    复制代码
    --answer:
    select orderid,orderdate,custid,empid
    from Sales.Orders
    where orderdate in (
    select max(orderdate) from Sales.Orders
    )
    /*
    1.处理嵌套在外层查询语句里的子查询,应用max函数从表Sales.Orders中查找orderdate最后一天的日期,生成虚拟表VT1,
    2.处理嵌套在外层的查询语句,从Sales.Orders表中查找满足where条件orderdate在虚拟表VT1中有相等值的数据,得到虚拟表VT2
    3.处理select列表,从虚拟表VT2中查找出custid,orderdate,custid,empid返回虚拟表VT3
    */
    复制代码
    复制代码
    /*2:写一条查询语句,并返回2008年5月1号(包括这一天)以后没有处理过的订单的雇员。
    涉及到表:HR.Employees表和Sales.Orders表。
    期望的输出:*/
    empid       FirstName  lastname
    ----------- ---------- --------------------
    3           Judy       Lew
    5           Sven       Buck
    6           Paul       Suurs
    9           Zoya       Dolgopyatova
    复制代码

    参考SQL:

    复制代码
    --answer:
    select empid,firstname,lastname
    from HR.Employees 
    where empid not in(
    select o.empid
    from Sales.Orders as o
    where o.orderdate>='2008-05-01'
    )
    
    /*
    1.处理嵌套在外层查询语句里的子查询,表Sales.Orders别名o
    2.查找满足where条件 o.orderdate>='2008-05-01',生成虚拟表VT1
    3.从虚拟表VT1中处理select列表,查找出empid生成虚拟表VT2
    4.处理嵌套在外层的查询语句,从Sales.Orders表中查找满足where条件empid不在虚拟表VT2中有相等值的数据,得到虚拟表VT3
    5.处理select列表从虚拟表VT3中查找empid,firstname,lastname返回虚拟表VT4
    */
    复制代码
    复制代码
    /*3:写一条查询语句,返回订购了第12号产品的客户。
    涉及的表:Sales.Customers表和Sales.Orders表。
    期望的输出:*/
    custid      companyname
    ----------------------------------------
    48          Customer DVFMB
    39          Customer GLLAG
    71          Customer LCOUJ
    65          Customer NYUHS
    44          Customer OXFRU
    51          Customer PVDZC
    86          Customer SNXOJ
    20          Customer THHDP
    90          Customer XBBVR
    46          Customer XPNIK
    31          Customer YJCBX
    87          Customer ZHYOS
    复制代码

    参考SQL:

    复制代码
    --answer:
    SELECT custid, companyname
    FROM Sales.Customers AS C
    WHERE EXISTS
      (SELECT *
       FROM Sales.Orders AS O
       WHERE O.custid = C.custid
         AND EXISTS
           (SELECT *
            FROM Sales.OrderDetails AS OD
            WHERE OD.orderid = O.orderid
              AND OD.ProductID = 12));
    /*
    1.先处理外层查询,从Sales.Customers表别名C中取出一个元组,将元组相关列值custid传给内层查询
    2.执行第一层内层查询,Sales.Orders表别名O中取出一个元组,将元组相关列值custid传给内层查询
    3.执行第二层内层查询,Sales.Orders表别名OD应用where子句返回满足条件OD.orderid = O.orderid和 OD.ProductID = 12的值
    4.返回到第一层内层查询中,应用where子句返回满足条件O.custid = C.custid和EXISTS条件的值
    5.返回到外层查询处理 EXISTS,外查询根据子查询返回的结果集得到满足条件的行
    */
    复制代码
  • 相关阅读:
    HDU 6187 Destroy Walls
    HDU1596 find the safest road
    美国机遇号失联已久,NASA想出一奇招,网友看后:这我上我也行!
    萨拉飞机或掉入恐怖深渊,那里满是核废料
    Problem : 恢复一棵树
    Problem : [tju1071]一个简单题
    Problem : 马农
    人类首个“触日”探测器绕日第二圈
    美国三岁男孩森林迷路两天 遇黑熊“热心帮忙”终获救
    世上最孤独鸭子去世
  • 原文地址:https://www.cnblogs.com/8080zl/p/8603113.html
Copyright © 2020-2023  润新知