zoukankan      html  css  js  c++  java
  • TSQL中的子查询,一步步详细说明

    假设你需要Orders表,并且想返回每一条order的信息,并且包括前一条order的ID(在本例中就是orderid, orderdate, empid, custid,prevorderid),。但是你知道在表中的行记录是没有顺序的,这时我们需要把概念转换成SQL的等价思想:最大的值小于当前的值

    用SQL语句表示如下
     
    SELECT orderid, orderdate, empid, custid,
    (SELECT MAX(O2.orderid)
    FROM Sales.Orders AS O2
    WHERE O2.orderid < O1.orderid) AS prevorderid
    FROM Sales.Orders AS O1;
    在我第一看到O2.orderid < O1.orderid这种形式的比较的时候,我最想明白的就是O1.orderid的取值是什么?
    其实,连接外部的子查询就相当于
    for(){
      for(){
      }
    }
    也就是说,Order表中的每一行都和Order表整张表进行比较,这个是通过别名来实现的。 
    因此我们很容易理解,01.orderid的取值是按照表中记录的原本顺序的第一条记录。因此表中的O1.orderid = 10248。
    接着的MAX(O2.orderid),比如说小于10250的结果集是10248和10249,选择最大的当然是10249了。
    这个是查询结果
    orderid     orderdate                   empid       custid      prevorderid
    ----------- --------------------------- ----------- ----------- -----------
    10248 2006-07-04 00:00:00.000 5 85 NULL
    10249 2006-07-05 00:00:00.000 6 79 10248
    10250 2006-07-08 00:00:00.000 4 34 10249
    10251 2006-07-08 00:00:00.000 3 84 10250
    10252 2006-07-09 00:00:00.000 4 76 10251
    ...
    11073 2008-05-05 00:00:00.000 2 58 11072
    11074 2008-05-06 00:00:00.000 7 73 11073
    11075 2008-05-06 00:00:00.000 8 68 11074
    11076 2008-05-06 00:00:00.000 4 9 11075
    11077 2008-05-06 00:00:00.000 1 65 11076

    (830 row(s) affected)
     
     
    
    
    单独看上面的说明,我想初学者可能还是不明白,因此最后我再完整的阐述下整个运行过程
    SELECT orderid, orderdate, empid, custid,
    (SELECT MAX(O2.orderid)
    FROM Sales.Orders AS O2
    WHERE O2.orderid < O1.orderid) AS prevorderid
    FROM Sales.Orders AS O1;



    1.给Sales.Orders设置别名O1
    2.O1.orderid 转换成 Sales.Orders表的第一条记录(10248)。
    所以这时应该是
    (SELECT MAX(O2.orderid)
    FROM Sales.Orders AS O2
    WHERE O2.orderid < 10248
    )
    接着返回查询的结果集null,因为不存在比10248还小的orderid
    3.外部查询有了第一行记录。
    4.自引用产生了遍历效果 Select产生了遍历效果,因此再度进入到子查询里,这时子查询变为
    (SELECT MAX(O2.orderid)
    FROM Sales.Orders AS O2
    WHERE O2.orderid < 10249
    )
    返回查询结果集为10248,MAX后仍然是10248。
    5.外部查询有了第二行记录
    6.继续进入到子查询
    (SELECT MAX(O2.orderid)
    FROM Sales.Orders AS O2
    WHERE O2.orderid < 10250
    )
    返回的查询结果集为10249和10248,MAX后返回的是10249
    7.外部查询有了第三条记录
    接下来的依次类推
  • 相关阅读:
    Leetcode888. 公平的糖果棒交换
    Leetcode81. 搜索旋转排序数组 II
    Leetcode80. 删除排序数组中的重复项 II
    Leetcode1631. 最小体力消耗路径
    Leetcode57. 插入区间
    Leetcode724. 寻找数组的中心索引
    Leetcode18. 四数之和
    Leetcode110. 平衡二叉树
    Leetcode1128. 等价多米诺骨牌对的数量
    python 集合和深浅copy
  • 原文地址:https://www.cnblogs.com/lwzz/p/1947565.html
Copyright © 2011-2022 走看看