每个日期的聚合

时间:2017-02-06 16:22:41

标签: sql sql-server sum

我列出了数千家公司,但仅供参考;我引用了两家公司。我需要生成TotalSales列,其中值是每个公司的销售额的总和,在相应的实际年份之前的一年和四分之一。

Company         Sales   Quarter    Year      TotalSales    QtrYr_Included
ABC Inc.        10,000     1       2010         null       Q12009 - Q42009
ABC Inc.        50,000     2       2010        10,000      Q22009 - Q12010
ABC Inc.        35,000     3       2010        60,000      Q32009 - Q22010 
ABC Inc.        15,000     4       2010        95,000      Q42009 - Q32010
ABC Inc.         5,000     1       2011        110,000     Q12010 - Q42010
ABC Inc.        10,000     2       2011        105,000     Q22010 - Q12011
SoKor Group     50,000     1       2009         null       Q12008 - Q42008
SoKor Group     10,000     2       2009        50,000      Q22008 - Q12009
SoKor Group     10,000     3       2009        60,000      Q32008 - Q22009
SoKor Group      5,000     4       2009        70,000      Q42008 - Q32009
SoKor Group     15,000     1       2010          .         Q12009 - Q42009
SoKor Group     20,000     3       2010          .         Q22009 - Q12010

非常感谢你。

2 个答案:

答案 0 :(得分:3)

以下是使用Sum Over窗口聚合

执行此操作的一种方法
SELECT *,
       Sum(sales)
         OVER(
           partition BY Company
           ORDER BY [Year], [Quarter] ROWS BETWEEN 4 PRECEDING AND 1 PRECEDING)
FROM   Yourtable

旧版本

;WITH cte
     AS (SELECT Row_number()OVER(partition BY Company ORDER BY [Year], [Quarter]) rn,*
         FROM   Yourtable a)
SELECT *
FROM   cte a
       CROSS apply (SELECT Sum (sales) Total_sales
                    FROM   (SELECT TOP 4 sales
                            FROM   cte b
                            WHERE  a.Company = b.Company
                                   AND b.rn < a.rn
                            ORDER  BY [Year] DESC,
                                      [Quarter] DESC)a) cs

答案 1 :(得分:0)

@ Prdp的解决方案是有效的。但是,当给定公司缺少季度时,它会显示不正确的结果,因为它将考虑丢失行之前可用的任何行。避免这种情况的一种方法是使用派生表生成年,季度和公司的所有组合。左边加入原始表格到这个结果将为缺少的季度产生0销售。然后使用sum窗口函数获取每行最后4个季度的销售总和。

SELECT *
FROM
 (SELECT C.COMPANY,
         Y.[YEAR],
         Q.[QUARTER],
         T.SALES,
         SUM(COALESCE(T.SALES,0)) OVER(PARTITION BY C.COMPANY
                                       ORDER BY Y.[YEAR], Q.[QUARTER] 
                                       ROWS BETWEEN 4 PRECEDING AND 1 PRECEDING) AS PREV_4QTRS_TOTAL
  FROM
   (SELECT 2008 AS [YEAR]
    UNION ALL SELECT 2009
    UNION ALL SELECT 2010
    UNION ALL SELECT 2011
    UNION ALL SELECT 2012
    UNION ALL SELECT 2013) Y --Add more years as required or generate them using a recursive cte or a tally table
  CROSS JOIN
   (SELECT 1 AS [QUARTER]
    UNION ALL SELECT 2
    UNION ALL SELECT 3
    UNION ALL SELECT 4) Q
  CROSS JOIN
   (SELECT DISTINCT COMPANY
    FROM T) C
  LEFT JOIN T ON Y.[YEAR]=T.[YEAR]
  AND Q.[QUARTER]=T.[QUARTER]
  AND C.COMPANY=T.COMPANY 
) X
WHERE SALES IS NOT NULL --to filter the result to include only rows from the original table
ORDER BY 1,2,3

Sample Demo