SQL Pivot 未对所有结果求和

Posted

技术标签:

【中文标题】SQL Pivot 未对所有结果求和【英文标题】:SQL Pivot not summing all results 【发布时间】:2014-03-03 09:00:12 【问题描述】:

我最近尝试制作一个 SQL PIVOT,但我发现它不太正常。这是我正在使用的

SQL Server 2005 使用供应商视图的供应商数据库 - 我无法创建额外的表或视图或直接查询数据表(长篇大论)

我每月查询一组包含多个条目的数据,然后将其与第二组联合起来,形成我所说的数据集。我正在使用 CASE WHEN 对对象进行分组(即 dbid 1、7 和 10 的结果是“a”,2,3 和 9 是“b”等。

我正在旋转数据集以按月显示交易量的总和。

我的问题是其中一列,它没有计算数据集中似乎是一年中一个月的所有结果。经过仔细调查,我发现缺少的数据似乎是两行数据在下面的查询中具有相同的 N_Entered 值)。

我已经设法使用通用查询(如下)重新创建了问题。我已经在 sql server express 2008 r2 和 sql server 2005 上运行了它,我得到了相同的结果 - 这是

Begin_Time 总计 A 苹果 B 香蕉 香蕉 C 胡萝卜 胡萝卜 D 狗 狗 2014-02-01 00:00:00.000 174732 44000 4591 581 208

2014 年 2 月 B 的总和为 4594,但此查询返回 4591。您会注意到表一中 2 月的“B”的两个条目的 N_Entered 为“3”。

如果我删除将数据集与 table2 联合的部分 - 我得到正确答案 - 4594。

我 100 万美元的问题是

    如何在数据透视表中获得正确的结果? 为了我自己的学习 - 我做错了什么?

此代码与我的生产查询之间的差异是

我从生产中的视图中选择,而不是使用表变量 结果生产跨度超过一年,我只是保留了 'datediff 子句,以尽量保持它尽可能接近。

非常感谢!

declare @vartable as table (Begin_Time DateTime, Letter varchar(30), N_Entered int) 
declare @vartable2 as table (Begin_Time DateTime, Letter varchar(30), N_Entered int) 

--populate first table
insert into @vartable (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'D', 125) 
insert into @vartable (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'B', 2519) 
insert into @vartable (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'A', 23) 
insert into @vartable (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'A', 271) 
insert into @vartable (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'B', 9) 
insert into @vartable (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'B', 3) 
insert into @vartable (Begin_Time, Letter, N_Entered) Values  ('2014-02-01 00:00:00', 'B', 37) 
insert into @vartable (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'A', 357) 
insert into @vartable (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'A', 24230) 
insert into @vartable (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'A', 9) 
insert into @vartable (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'D', 83) 
insert into @vartable (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'B', 1998) 
insert into @vartable (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'A', 13) 
insert into @vartable (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'A', 217) 
insert into @vartable (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'B', 3) 
insert into @vartable (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'B', 1) 
insert into @vartable (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'B', 24) 
insert into @vartable (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'A', 212) 
insert into @vartable (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'A', 18656) 
insert into @vartable (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'A', 12) 
insert into @vartable (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'C', 272) 
insert into @vartable (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'C', 309) 

--populate second table
insert into @vartable2 (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'T',  1009) 
insert into @vartable2 (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'T', 90810) 
insert into @vartable2 (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'T', 198) 
insert into @vartable2 (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'T', 253) 
insert into @vartable2 (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'T', 447) 
insert into @vartable2 (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'T', 829) 
insert into @vartable2 (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'T', 80427) 
insert into @vartable2 (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'T', 152) 
insert into @vartable2 (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'T', 149) 
insert into @vartable2 (Begin_Time, Letter, N_Entered) Values ('2014-02-01 00:00:00', 'T', 458) 

SELECT * FROM 
(SELECT Begin_Time, 
CASE Letter 
        WHEN 'A' THEN 'A Apples' 
        WHEN 'B' THEN 'B Banana Bananas' 
        WHEN 'C' THEN 'C Carrot Carrots' 
        WHEN 'D' THEN 'D Dog Dogs' 
ELSE Letter 
END 'Option Selected' 
, N_Entered 
From @vartable 
WHERE (Datediff(month, begin_time, getdate()) Between 1 and 12) 
AND Letter IN ( 'A', 'B', 'C', 'D' )  -- end first select 

--removing this union section does give the right answer

UNION 
( 
SELECT Begin_Time, 'Totals' as 'Total Numbers', Sum(N_Entered) As N_Entered 
        FROM @vartable2 
                WHERE   

                          Letter IN ('T') 
                         AND (Datediff(month, begin_time, getdate()) Between 1 and 12) 
                GROUP BY begin_time 
        )  -- end second select 

-- end of union section

) As Data 

PIVOT 

( 
SUM(N_ENTERED) 
FOR [Option Selected] IN ([Totals], [A Apples], [B Banana Bananas], [C Carrot Carrots], [D Dog Dogs]) 
) 
As PivotTable;

【问题讨论】:

【参考方案1】:

用 Union ALL 替换 Union

Union 正在消除重复值,即 B 中的值 3。Union ALL 会考虑它。

【讨论】:

以上是关于SQL Pivot 未对所有结果求和的主要内容,如果未能解决你的问题,请参考以下文章

Sql Server 数据透视表未对结果集进行分组

sql对查询结果求和

SQL 中的 Pivot 语法错误,为啥我得到不正确的结果?

Sql PIVOT,如何使用 PIVOT 将结果中的 NULL 转换为值 0

每个结果多行的 SQL Pivot

SQL Pivot - 查询结果垂直到水平