from子句中的子查询如何工作?

时间:2013-08-29 05:09:04

标签: sql oracle subquery

FROM子句中Sub Query的有效用例是什么?该计划如何运作?在SO中有很多这种类型的例子。其中一个链接是here,但我看不出这个方案是如何运作的。

P.S:如果答案是针对Oracle的,那就很好。

1 个答案:

答案 0 :(得分:2)

以下是from子句中子查询的一些用例。它的工作原理已经在你的问题的评论中解释了(由于它的关系运算符,SQL是数学闭合的)。

<强> 1。 Pivot(SQL Server 2008)

 select P.RUN_ID
      , [2012] = sum(P.[2012])
      , [2013] = sum(P.[2013])
      , [2014] = sum(P.[2014])
      , [2015] = sum(P.[2015])
   from (select T.RUN_ID
              , Y.YEAR
              , T.MEASURE
           from SOME_TABLE T
          inner join
                YEAR Y
                  on T.SOME_ID = Y.SOME_ID
        ) T
  pivot (
          sum(MEASURE)
          for YEAR in ([2012], [2013], [2014], [2015])
        ) P
  group by
        P.RUN_ID
  order by
        P.RUN_ID

<强> 2。基于联合的over子句(Oracle)

 select S.Text_ID
      , row_number() over (partition by S.Text_ID order by S.Segmentstart) as Segmentnumber
      , S.Segment_ID
      , S.Segmentstart
      , S.Segmentend
      , S.Segmentfragment
   from (select S.Text_ID as Text_ID
              , S.Satz_ID as Segment_ID
              , S.Start as Segmentstart
              , S.End as Segmentend
              , S.Fragment as Segmentfragment
           from Mainclauses S
          union all
         select X.ID as Text_ID
              , null as Segment_ID
              , coalesce(S.End, 0) as Segmentstart
              , lead(S.Start, 1, X.CONTENT_LENGTH) over (partition by X.ID order by S.Start) as Segmentend
              , 'X' as Segmentfragment
           from Texts X
           left join
                Mainclauses S
                  on X.ID = S.Text_ID
          union all
         select X.ID as Text_ID
              , null as Segment_ID
              , 0 as Segmentstart
              , min(S.Start) as Segmentend
              , 'X' as Segmentfragment
           from Texts X
          inner join
                Mainclauses S
                  on X.ID = S.Text_ID
          group by
                X.ID
        ) S

第3。带有连接和聚合的over子句(SQL Server 2008)

 select E.X_ID
      , Z.SomeThing
      , sum(Z.OtherMeasure * E.Measure) as CombinedMeasure
      , Sorting = row_number() over
          ( partition by
                      E.X_ID
                order by
                      Z.SomeThing
          )
   from (select E.X_ID
              , E.Y_ID
              , Measure = sum(E.Measure)
           from SomeTable E
          group by
                E.X_ID
              , E.Y_ID
        ) E
  inner join
        OtherTable Z
           on E.Y_ID     = Z.Y_ID

<强> 4。计算比率(SQL Server 2008)

   with SomeData
      ( Main_ID
      , Sub_ID
      , Measure
      )
   as (select Main_ID
            , Sub_ID
            , Measure = sum(Measure)
         from SomeTable P
        group by
              Main_ID
            , Sub_ID
      )
 select Main_ID
      , Sub_ID
      , Ratio = D.Measure / sum(M.Measure) over (partition by M.Main_ID)
   from SomeData D
  inner join
        (select Main_ID
              , Measure = sum(Measure)
           from SomeData
          group by
                Main_ID
         having sum(Measure) != 0
        ) M
           on M.Main_ID = D.Main_ID

<强> 5。两个(或更多)表的部分比较(SQL Server 2008)

select *
  from (select A, M = sum(M) from S group by A) X
  full outer join
       (select A, M = sum(M) from T group by A) Y
          on X.A = Y.A
 where X.A is null
    or Y.A is null
    or abs(X.M - Y.M) > 0.00000001

注意:这些只是示例,我认为from子句中的子查询是实现结果的好方法。