2017-02-06 37 views
2

我有成千上萬的公司上市,但爲了說明;我引用了2家公司。我需要生成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 

非常感謝。

+0

將表*始終*對所有宿舍的公司數據? –

+0

..在這種情況下,您是否必須將缺失的季度數據視爲0,並按特定順序報告總數或考慮不同年份的季度? –

+0

@ mnms2 - 您正在使用哪個版本的sql server? –

回答

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 
+0

Prdp ..這裏假定沒有任何部分丟失數據。您還應該顯示缺少數據時發生的情況並解釋替代方法。 –

+0

@vkp - 有效點..將更新.. –

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