从SQL查询中删除重复的代码

时间:2013-07-18 12:08:51

标签: sql query-optimization ssms

我创建了一个SQL查询,它按预期工作,但在SELECT语句中使用了大量重复代码来计算值。

例如在我的SQL语句中这一行:

SUM(od.Number01) OVER (ORDER BY od.Number01)

在不同的公式中重复几个SELECT条件。

E.g。

(rd.OurQty - SUM(od.Number01) OVER (ORDER BY od.Number01) + od.Number01) AS 'Left In Stock'

CASE WHEN (rd.OurQty - SUM(od.Number01) 
OVER (ORDER BY od.Number01) + od.Number01) - od.Number01 > 0 THEN od.Number01 ELSE (CASE WHEN (rd.OurQty - SUM(od.Number01) OVER (ORDER BY od.Number01) 
+ od.Number01) > 0 THEN (rd.OurQty - SUM(od.Number01) OVER (ORDER BY od.Number01) + od.Number01) ELSE 0 END) END AS 'Allocated'

对于小型数据集,这不是一个太大的问题。然而,当数据集变大时会出现问题。

如何在每行计算中存储此语句的结果,然后在所需的计算中使用存储在整个SELECT语句中的局部变量中的结果,而不是多次执行相同的计算?

我正在使用Microsoft SQL Server Management Studio 2012

2 个答案:

答案 0 :(得分:4)

为什么不使用CTE来定义SUM,然后再使用它?

  

公用表表达式(CTE)可以被认为是临时表   在单个执行范围内定义的结果集   SELECT,INSERT,UPDATE,DELETE或CREATE VIEW语句。 CTE是   类似于派生表,因为它不存储为对象和   仅持续查询的持续时间。与派生表不同,a   CTE可以是自引用的,可以多次引用   相同的查询。

这样的东西
WITH Vals AS (
    SELECT  *,
            SUM(Number01) OVER(ORDER BY Number01) MySum
    FROM    MyTable
)
SELECT *,
        MySum
FROM Val

SQL Fiddle DEMO

答案 1 :(得分:0)

在Oracle中,我已经这样做了(我认为你可以为SQL Server的方言修复它):

select
  case
    when (sq.ourqty - sq.number01_sum + sq.number01) - sq.number01 > 0
      then
        sq.number01
    else
      case
        when (sq.ourqty - sq.number01_sum + sq.number01) > 0
          then 
            sq.ourqty - sq.number01_sum + sq.number01
          else
            0
      end
  end as allocated
  , ...
from
(
select sum(od.number01) over (order by od.number01) as number01_sum
       , od.number01 as number01
       , rd.ourqty as ourqty
       , ...
from anytable1 od
     , anytable2 rd
where ...
) sq