2016-09-19 71 views
2

我试图获得按年份和国家/地区分组的总销售额。这按预期工作:使用GROUP BY和OVER

SELECT Year, Country, SUM([Total Sales]) 
FROM Table 
GROUP BY Country, Year; 

然后,我必须比较每个国家对一年总销售额的贡献。我这样做:

SELECT Year, Country, SUM([Total Sales]), 
    SUM([Total Sales]) OVER(PARTITION BY Year) 
FROM Table 
GROUP BY Country, Year; 

这给了我这个错误:

Column 'Table.Total Sales' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

回答

4

您需要嵌套的款项:

SELECT Year, Country, SUM([Total Sales]), 
     SUM(SUM([Total Sales])) OVER (PARTITION BY Year) 
FROM Table 
GROUP BY Country, Year; 

第一次看到它时,这个语法有点时髦。但是,窗口函数在,GROUP BY之后被评估为。这说的是总和销售额的总和。 。 。正是你想要的。

2

这是因为你可以用SUM()GROUP BY并与你的窗口功能的窗口级别查询级别不聚集。这是因为窗口函数在应用了结果集之后发生,包括GROUP BY。在那个时间点,[total sales]列仅在原始表格中作为非聚合字段存在,因此您最终会发现无意义。你可以先聚集在子查询,然后做最重要的是你的窗口:

SELECT Year, Country, Total_Sales, SUM([Total_Sales]) OVER(PARTITION BY Year) 
FROM 
(
    SELECT Year, Country, SUM([Total Sales])  
    FROM Table 
    GROUP BY Country, Year 
) sub 
+1

您的第一句话是误导性的,因为您可以在不使用子查询的情况下合并窗口函数和聚合函数。 –

0

我想你可以不用GROUP BY子句通过以下方式:

SELECT 
    Year, 
    Country, 
    SUM([Total Sales]) OVER(), 
    SUM([Total Sales]) OVER (PARTITION BY Year) 
FROM Table 
0

正如提到的错误,您需要在Group by中添加列当前窗口集合函数,但这会导致聚合错误。

如果你想找到的每个companyyear的贡献尝试这样的事情

SELECT year, 
     country, 
     Sum([total sales]), 
     OA.year_total, 
     (Sum([total sales])/NULLIF(OA.year_total,0)) * 100 AS Percent_contribution 
FROM table 
     OUTER apply (SELECT Sum(b.[total sales]) AS year_total 
        FROM table b 
        WHERE a.year = b.year) OA 
GROUP BY country, 
      year, 
      year_total; 

Outer Apply,这里将计算出每个year的总和。我们可以用总和发现各公司的贡献

使用JOIN

;WITH cte 
    AS (SELECT b.year, Sum(b.[total sales]) AS year_total 
     FROM table b 
     GROUP BY b.year) 
SELECT year, 
     country, 
     Sum([total sales]), 
     b.year_total, 
     (Sum([total sales])/NULLIF(b.year_total, 0)) * 100 AS Percent_contribution 
FROM table a 
     JOIN cte b 
     ON a.year = b.year 
GROUP BY year, 
      country, 
      b.year_total 
0

另一种方法尝试

SELECT distinct Year, Country, SUM([Total Sales]) OVER(PARTITION BY Country, Year) sumbycountryyear, SUM([Total Sales]) OVER(PARTITION BY Year) sumbyyear 
FROM Table