优化查询累积结果

时间:2014-05-18 11:08:31

标签: sql sql-server sql-server-2008

我有这个查询来查找一年中每个月的项目数。但我正在寻找累积结果的优化查询

SELECT 
 COUNT(ITM.ID) AS ItemCount,
 Month(ITM.ItemProcureDate),
 Year(ITM.ItemProcureDate)
    FROM 
    Rpt_Item ITM
    WHERE 
    ITM.ItemProcureDate IS NOT NULL       
    AND 
    ITM.ItemStatusID = 2         --       Item sold, Item Rejected 
    AND 
    ITM.ItemProcureDate >= CONVERT(DATETIME,'02/01/2014',1)   --@Beg_Date 
    AND 
    ITM.ItemProcureDate <= CONVERT(DATETIME,'04/12/2014',1)   --@End_Date 
    GROUP BY
    Month(ITM.ItemProcureDate),
    Year(ITM.ItemProcureDate) 

查询结果应如下所示:

Item sold In month      2
Item Sold Till Month        2
Item Rejected           1       
Item Rejected Till Month    1
Year                2014
Month               Feb
Last Date of Month      02/28/2014

-----------------------------------------------
Item sold In month      2
Item Sold Till Month        4
Item Rejected           1       
Item Rejected Till Month            2
Year                2014
Month               March
LastDate of Month       03/31/2014

-----------------------------------------------
Item sold In month      2
Item Sold Till Month        6
Item Rejected           1       
Item Rejected Till Month    3
Year                2014
Month               April
Last Date of Month      04/30/2014

我必须找到最近三个月的Item_Sold,Item_Rejected,Item_Added,其中每个月都应该累积所有前几个月的Item_Sold,Item_Rejected,Item_Added

1 个答案:

答案 0 :(得分:0)

在SQL Server 2008中,您可以使用相关子查询或使用非等值连接来执行此操作。 SQL Server 2012支持累积和函数。以下是使用相关子查询执行此操作的方法:

with ym as (
      SELECT COUNT(ITM.ID) AS ItemCount,
             Month(ITM.ItemProcureDate) as mon, Year(ITM.ItemProcureDate) as yr,
             Month(ITM.ItemProcureDate) + 100*Year(ITM.ItemProcureDate) as yyyymm
      FROM Rpt_Item ITM
      WHERE ITM.ItemProcureDate IS NOT NULL AND 
            ITM.ItemStatusID = 2 AND 
            ITM.ItemProcureDate >= CONVERT(DATETIME,'02/01/2014',1) AND 
            ITM.ItemProcureDate <= CONVERT(DATETIME,'04/12/2014',1)
      GROUP BY Month(ITM.ItemProcureDate), Year(ITM.ItemProcureDate) 
     )
select ym.*,
       (select sum(ItemCount)
        from ym ym2
        where ym.yyyymm <= ym.yyyy.mm
       ) as cumsum
from ym;

请注意,这会将年月变为YYYYMM格式。这只是一个方便,因此时间段上的比较只使用一列。

此外,如果ITM表格非常大或者是一个视图,那么这可能不如人们想象的那样好。如果性能是个问题,请使用临时表而不是CTE。 (SQL Server往往不会实现CTE,因此可能会运行代码两次。)