Sql 使用GROUP BY和OVER

Sql 使用GROUP BY和OVER,sql,sql-server,Sql,Sql Server,我想把总销售额按年份和国家分组。这与预期的效果一样: 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

我想把总销售额按年份和国家分组。这与预期的效果一样:

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;
这给了我一个错误:

列“Table.Total Sales”在选择列表中无效,因为它是 不包含在聚合函数或GROUP BY子句中


这是因为您不能在查询级别使用
SUM()
groupby
进行聚合,也不能在窗口级别使用window函数进行聚合。原因是,在对结果集应用了所有其他功能(包括
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

我想您可以不使用GROUP BY子句,通过以下方式进行操作:

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

如错误中所述,您需要在
Group by
中添加列present windowed aggregate函数,但这将导致聚合错误

如果您想查找每个
公司
的贡献,请尝试以下方法

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; 
外部应用
此处将计算每个
年度的总和
。我们可以用总数来计算每家公司的贡献

使用
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 
试试看


您需要将金额嵌套:

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

这种语法在你第一次看到它时有点古怪。但是,窗口函数是在
分组后由
计算的。这说明的是总销售额的总和。这正是您想要的。

您的第一句话有误导性,因为您可以在不使用子查询的情况下组合窗口函数和聚合函数。
SELECT Year, Country, SUM([Total Sales]),
       SUM(SUM([Total Sales])) OVER (PARTITION BY Year) 
FROM Table
GROUP BY Country, Year;