如何重新组合嵌套选择?

时间:2015-11-24 10:47:16

标签: sql oracle

我有累积总和的这种请求(这是一个简化的例子)

INSERT INTO DEMO (a,b,c,d,e)
  SELECT 
    DATA.a,
    NVL((SELECT SUM r2.x FROM EXAMPLE r2 WHERE r2.a = r1.a AND r2.i <= r1.i),0),
    DATA.c,
    NVL((SELECT SUM r2.y FROM EXAMPLE r2 WHERE r2.a = r1.a AND r2.i <= r1.i),0),
    DATA.e
  FROM
    DATA
    LEFT OUTER JOIN EXAMPLE r1 ON DATA.a = r1.a

此请求有效,但速度极慢。由于嵌套选择看起来都相同,我想重新组合它们。像

这样的东西
SELECT SUM r2.x, SUM r2.y FROM EXAMPLE r2 WHERE r2.a = r1.a AND r2.i <= r1.i

但我无法成功实现这一目标。我该怎么做 ?

我试过了两次

INSERT INTO DEMO (a,c,e,b,d)
  SELECT 
    DATA.a,
    DATA.c,
    DATA.e
    (SELECT SUM r2.x, SUM r2.y FROM EXAMPLE r2 WHERE r2.a = r1.a AND r2.i <= r1.i)
  FROM DATA
  LEFT OUTER JOIN EXAMPLE r1
    ON DATA.a = r1.a

INSERT INTO DEMO (a,c,e,b,d)
  SELECT 
    DATA.a,
    DATA.c,
    DATA.e
  FROM DATA
  LEFT OUTER JOIN EXAMPLE r1
    ON DATA.a = r1.a
  UNION
  SELECT
    (SELECT SUM r2.x, SUM r2.y FROM EXAMPLE r2 WHERE r2.a = r1.a AND r2.i <= r1.i)
  FROM DATA
  LEFT OUTER JOIN EXAMPLE r1
    ON DATA.a = r1.a

1 个答案:

答案 0 :(得分:3)

使用自联接计算的累计和(运行总计)通常很慢,因为对于每条记录,必须再次读取所有匹配的前记录。

更好地使用分析函数SUM:

INSERT INTO DEMO (a,b,c,d,e)
  SELECT 
    DATA.a,
    NVL( SUM(x) OVER (PARTITION BY r1.a ORDER BY r1.i
                      RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) , 0),
    DATA.c,
    NVL( SUM(y) OVER (PARTITION BY r1.a ORDER BY r1.i
                      RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) , 0),
    DATA.e
  FROM DATA
  LEFT OUTER JOIN EXAMPLE r1
    ON DATA.a = r1.a