• 子查询


    一、独立子查询

          子查询独立于外部查询:可以把子查询代码独立出来单独运行

            Customers表中原始数据如下:

          Orders表中原始数据如下:


          1.独立单值子查询(独立标量子查询)

             子查询返回的是单个值,而不是数据集

    1 use edisondb;
    2  select *
    3  from customers as C
    4  where C.custid=(
    5 select O.custid
    6 from Orders as O
    7 where O.orderid=10248
    8 );

            查询结果为:

     注:使用单值独立子查询时,一定要保证子查询返回的是单个值,而不是数据集;

           若返回的是数据集,则会出现如下状况:

    1 use edisondb;
    2  select *
    3 from customers as C
    4 where C.custid=(
    5 select O.custid
    6 from Orders as O
    7 where O.orderid between 10248 and 10252
    8 );

            查询出错提示:

          2.独立多值子查询

             子查询返回的是数据集

    1 use edisondb;
    2 select *
    3 from customers as C
    4 where C.custid IN(
    5 select O.custid
    6 from Orders as O
    7 where O.orderid between 10248 and 10253
    8 );

             查询结果为:

                                  外部表行1

                              外部表行2

    二、相关子查询=       。        + 独立子查询

                                     。

                              外部表行n

          相关子查询最基本的执行逻辑是:将外部表中的 “每一行” 逐行代入到子查询中   (理解相关子查询的关键)

    1 use edisondb;
    2  select *
    3  from customers as C
    4  where exists (
    5 select *
    6 from Orders as O
    7 where O.custid=C.custid and (O.orderid between 10248 and 10252)
    8 );

          查询结果如下: 

      执行步骤: a)取Customers表中的第一行数据

                 

                     b)将“外部表”第一行的数据代入到子查询where条件中,并执行子查询,获取中间数据集

                          此时,子查询相当于执行如下语句:      

    1 use edisondb;
    2 select *
    3 from Orders as O
    4 where O.custid=86 and (O.orderid between 10248 and 10252);
                          获取的中间数据集如下:

                        

                     c)将子查询中获取的中间数据集,代入到外部查询的where条件中,决定是否返回外部表

                        第一行数据

                        该步骤中,要么返回第一行数据,要么返回空,而不是返回整张外部表的数据(不同于一般

                        的select *

                         

                          说明:如果外部查询where条件为true,返回该行数据;where条件为false,不返回任何内容。

                                   也就是说,以上的所有操作都只是为了确定是否返回外部表的第一行数据

                     d)然后不断重复以上操作,得到了最终结果:

                         外部表中的每行都重复前面的操作,将每一行操作返回的数据集进行合并,得到最终结果 

                        

    三、相关子查询与独立子查询之间的转换

           下面的“相关子查询”和“独立子查询”相互等价

           相关子查询:

    1 use edisondb;
    2  select *
    3  from customers as C
    4  where exists (
    5 select *
    6 from Orders as O
    7 where O.custid=C.custid and (O.orderid between 10248 and 10252)
    8 );

          独立子查询:

    1 use edisondb;
    2  select *
    3  from customers as C
    4  where C.custid in (
    5 select O.custid
    6 from Orders as O
    7 where O.orderid between 10248 and 10252
    8 );
    9

         查询结果均为:

        “相关子查询”转“独立子查询”:

                  将子查询中“外部表”的列上移至,外查询的where条件中 (需要改EXISTES为IN

        “独立子查询”“相关子查询”:

                  将外查询where条件中“外部表”的列下移至,子查询的where条件中(需要改IN为EXISTS

    注:EXISTS用于相关子查询中(使程序员重点关心,返回当前外部行的条件是否为真,而不考虑子查询中具体的列

          IN用于独立子查询中

    附:子查询联接查询的选择

            返回结果位于不同表中的列时,使用联接查询;

                                同一张表中的列时,使用子查询。

           

  • 相关阅读:
    Python中的除法
    使用Windows Live Writer 2012和Office Word 2013 发布文章到博客园全面总结
    单例模式(Singleton)的6种实现
    Linux关机命令总结
    Java中构造函数执行顺序的问题
    SVN四部曲之SVN命令精通
    SVN四部曲之SVN简单使用教程入门
    SVN四部曲之SVN使用详解进阶
    用正则表达式判断一个二进制数是否能被3整除
    栈帧%ebp,%esp详解
  • 原文地址:https://www.cnblogs.com/edisonfeng/p/2096403.html
Copyright © 2020-2023  润新知