Sql server 使用数据透视时在SQL Server 2012中未获取正确的总和值

Sql server 使用数据透视时在SQL Server 2012中未获取正确的总和值,sql-server,sql-server-2012,pivot,distinct,aggregate-functions,Sql Server,Sql Server 2012,Pivot,Distinct,Aggregate Functions,我正在尝试创建一个查询,该查询将围绕一些行,但将对一些列求和,然后将它们分组在一起。我以前使用过PIVOT函数,但是当我的结果集包含类似的值时,我遇到了问题 这是SQL Server 2012 示例代码: CREATE TABLE #Foo ( Store varchar(50), Employee varchar(50), Sold money, Waste money, Tmsp datetime ) INSERT INTO #Fo

我正在尝试创建一个查询,该查询将围绕一些行,但将对一些列求和,然后将它们分组在一起。我以前使用过
PIVOT
函数,但是当我的结果集包含类似的值时,我遇到了问题

这是SQL Server 2012

示例代码:

CREATE TABLE #Foo
(
     Store varchar(50), 
     Employee varchar(50), 
     Sold money, 
     Waste money, 
     Tmsp datetime
)

INSERT INTO #Foo 
VALUES
   ('Harrisburg', 'John', 20.00, 10.00, GETDATE()),
   ('Harrisburg', 'John', 20.00, 10.00, GETDATE()),
   ('Harrisburg', 'Jim', 20.00, 10.00, GETDATE()),
   ('Seattle', 'Jim', 20.00, 10.00, GETDATE()),
   ('Seattle', 'Alex', 20.00, 10.00, GETDATE())

SELECT 
    Store,
    SUM(Sold) TotalSold,
    SUM([John]) WastedByJohn,
    SUM([Jim]) WastedByJim,
    SUM([Alex]) WastedByAlex
FROM 
    #Foo
PIVOT
    (SUM(Waste)
     FOR Employee IN ([John], [Jim], [Alex])
    ) PVT
GROUP BY 
   Store

DROP TABLE #Foo
这将产生以下结果:

Store      | TotalSold | WastedByJohn | WastedByJim | WastedByAlex
Harrisburg | 20.00     | 20.00        | 10.00       | NULL
Seattle    | 20.00     | NULL         | 10.00       | 10.00
根据表中的数据,哈里斯堡的总销售额不应该是60.00,西雅图的总销售额不应该是40.00吗

这对我来说越来越难理解,因为如果我更改数据使值不相同,我会得到正确的结果

INSERT INTO #Foo 
VALUES
    ('Harrisburg', 'John', 25.00, 10.00, GETDATE()),
    ('Harrisburg', 'John', 30.00, 10.00, GETDATE()),
    ('Harrisburg', 'Jim', 40.00, 10.00, GETDATE()),
    ('Seattle', 'Jim', 50.00, 10.00, GETDATE()),
    ('Seattle', 'Alex', 60.00, 10.00, GETDATE())
这组数据产生了预期的结果:

Store      | TotalSold | WastedByJohn | WastedByJim | WastedByAlex
Harrisburg | 95.00     | 20.00        | 10.00       | NULL
Seattle    | 110.00    | NULL         | 10.00       | 10.00
我环顾了一下四周,没有找到一个答案,为什么在聚合方面,PIVOT会基于不同的值而有所不同。我觉得这里缺少一些基本的东西,除非我碰巧遇到SQL Server的一些问题,这是不可能的

任何帮助都将不胜感激


谢谢

以下查询应提供您想要的内容:

SELECT Store,
       TotalSold,
       [John] AS WastedByJohn,
       [Jim] AS WastedByJim,
       [Alex] AS WastedByAlex
FROM (SELECT Store, Employee, Waste,
             SUM(Sold) OVER (PARTITION BY Store) AS TotalSold
      FROM #Foo) src
PIVOT
    (SUM(Waste)
     FOR Employee IN ([John], [Jim], [Alex])
    ) PVT
要了解为什么会得到意外结果,请尝试在不使用
GROUP BY
子句的情况下进行查询:

SELECT Store, Sold, [John], [Jim], [Alex]
FROM 
    #Foo
PIVOT
    (SUM(Waste)
     FOR Employee IN ([John], [Jim], [Alex])
    ) PVT
输出:

Store       Sold    John    Jim     Alex
Harrisburg  20,00   20,00   10,00   NULL
Seattle     20,00   NULL    10,00   10,00
Store       Sold    John    Jim     Alex
Harrisburg  25,00   10,00   NULL    NULL
Harrisburg  30,00   10,00   NULL    NULL
Harrisburg  40,00   NULL    10,00   NULL
Seattle     50,00   NULL    10,00   NULL
Seattle     60,00   NULL    NULL    10,00
现在,对第二个版本的示例数据再次尝试相同的操作:

输出:

Store       Sold    John    Jim     Alex
Harrisburg  20,00   20,00   10,00   NULL
Seattle     20,00   NULL    10,00   10,00
Store       Sold    John    Jim     Alex
Harrisburg  25,00   10,00   NULL    NULL
Harrisburg  30,00   10,00   NULL    NULL
Harrisburg  40,00   NULL    10,00   NULL
Seattle     50,00   NULL    10,00   NULL
Seattle     60,00   NULL    NULL    10,00
通过比较两个不同的结果集,您可以清楚地看到,
PIVOT
针对未参与其中的每一列组合进行,即针对
Store
sall
的每一组合

在第一种情况下,只有哈里斯堡20,00和西雅图20,00。这就是为什么在这种情况下只能得到两行。在第二种情况下,总共有3+2=5个组合


现在,您可以了解为什么
groupby
只在第二种情况下起作用。

您没有得到pivot语句的作用。让我解释一下。首先有三个要素:传播、聚合和分组。 Spreading是您在列中得到的,即([John]、[Jim]、[Alex])中的员工。聚合是
总和(浪费)
。那么什么是分组元素呢?最后一个是通过消除列来确定的。即除聚合和扩展外的每一列。在您的示例中,它将是
存储、销售、Tps
。它将按这3列对数据进行分组。但你不想要这个。您只想按
存储
进行分组。那怎么办呢?我可以建议使用条件聚合:

SELECT 
    Store,
    SUM(Sold) TotalSold,
    SUM(CASE WHEN Employee = 'John' THEN Waste ELSE 0 END) WastedByJohn,
    SUM(CASE WHEN Employee = 'Jim' THEN Waste ELSE 0 END) WastedByJim,
    SUM(CASE WHEN Employee = 'Alex' THEN Waste ELSE 0 END) WastedByAlex
FROM #Foo
GROUP BY Store

如何在预期输出中获得95和110的总值?它应该是40和60,不是吗?我希望它是“售出”的总价值,按商店分组。在第一个例子中,我预计哈里斯堡是20+20+20=60,西雅图是20+20=40。有些东西似乎工作不正常,因为所有行的“sell”值都相同(20.00)。对于第二个数据集,“已售出”的值不同,并且总和正确(哈里斯堡为25+30+40=95,西雅图为50+60=110),非常感谢!“PIVOT发生在没有参与的每一列组合中,即,对于每一个商店组合,销售”是我所缺少的!