子查询

一、独立子查询

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

        Customers表中原始数据如下:

2011070218531587.jpg

      Orders表中原始数据如下:

2011070218552120.jpg

      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 );

        查询结果为:

2011070218584868.jpg

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

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

 
  
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 );

        查询出错提示:

2011070219023574.jpg

      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 );

         查询结果为:

2011070219062595.jpg

                              外部表行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 );

      查询结果如下: 

2011070217235791.jpg

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

              2011070217301332.jpg

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

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

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

                     2011070217390010.jpg

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

                    第一行数据

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

                    的select *)

                      2011070217495179.jpg

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

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

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

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

                     2011070218010244.jpg

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

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

       相关子查询:

 
  
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

     查询结果均为:

2011070218120768.jpg

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

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

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

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

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

      IN用于独立子查询中

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

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

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

       

转载于:https://www.cnblogs.com/edisonfeng/archive/2011/07/02/2096403.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值