PIVOT多列未考虑汇总结果

时间:2018-08-01 06:23:07

标签: sql sql-server

我正在尝试PIVOT多列数据。这是我尝试过的查询。

;WITH CTE(Project,Cost,spc,CostType)
AS
(
SELECT 'Project 1', 100 ,103,'Internal' UNION ALL
SELECT 'Project 1', 12  ,15,'External' UNION ALL
SELECT 'Project 2', 45  ,22,'Internal' UNION ALL
SELECT 'Project 2', 2   ,37,'External' UNION ALL
SELECT 'Project 2', 33  ,46,'Internal' UNION ALL
SELECT 'Project 3', 42  ,11,'External' UNION ALL
SELECT 'Project 4', 57  ,5,'Internal' UNION ALL
SELECT 'Project 5', 22  ,77,'Internal' UNION ALL
SELECT 'Project 5', 17  ,9,'External' 
)
SELECT Project,
        ISNULL([Internal],0) AS [Internal],
        ISNULL([External],0) AS [External],
        ISNULL([Internal2],0) AS [InternalSPC],
        ISNULL([External2],0) AS [ExternalSPC]
FROM
(
SELECT Project,
        Cost,
        spc,
        CostType,
        CostType+'2' as CostType2
from CTE
)AS SRC
PIVOT
(
SUM(Cost) FOR CostType IN ([Internal],[External])
)
AS PVT

PIVOT
(
SUM(spc) FOR CostType2 IN ([Internal2],[External2])
)
AS PVT

得到的结果如下

enter image description here

但是预期结果是

 Project     Internal     External     InternalSPC     ExternalSPC
----------------------------------------------------------------------
 Project 1     100          12          103                15
 Project 2     78           2            68               37
 Project 3     0            42          0                 11
 Project 4     57           0             5               0
 Project 5     22          17          77               9

我不了解我的查询问题

根据答案进行编辑

对此的第一个答案是使用分组。但是奇怪的是,如果不考虑分组而只考虑其预期工作的一列。 检查此查询,我仅考虑一列

;WITH CTE(Project,Cost,spc,CostType)
AS
(
SELECT 'Project 1', 100 ,103,'Internal' UNION ALL
SELECT 'Project 1', 12  ,15,'External' UNION ALL
SELECT 'Project 2', 45  ,22,'Internal' UNION ALL
SELECT 'Project 2', 2   ,37,'External' UNION ALL
SELECT 'Project 2', 33  ,46,'Internal' UNION ALL
SELECT 'Project 3', 42  ,11,'External' UNION ALL
SELECT 'Project 4', 57  ,5,'Internal' UNION ALL
SELECT 'Project 5', 22  ,77,'Internal' UNION ALL
SELECT 'Project 5', 17  ,9,'External' 
)
SELECT Project,
        ISNULL([Internal],0) AS [Internal],
        ISNULL([External],0) AS [External]
FROM
(
SELECT Project,
        Cost,
        CostType
from CTE
)AS SRC
PIVOT
(
SUM(Cost) FOR CostType IN ([Internal],[External])
)
AS PVT

上述查询的结果如下

enter image description here 我不明白为什么它在不分组的情况下也能很好地用于1列透视图。

3 个答案:

答案 0 :(得分:3)

尝试一下:在项目列中使用分组依据并进行汇总

;WITH CTE(Project,Cost,spc,CostType)
AS
(
SELECT 'Project 1', 100 ,103,'Internal' UNION ALL
SELECT 'Project 1', 12  ,15,'External' UNION ALL
SELECT 'Project 2', 45  ,22,'Internal' UNION ALL
SELECT 'Project 2', 2   ,37,'External' UNION ALL
SELECT 'Project 2', 33  ,46,'Internal' UNION ALL
SELECT 'Project 3', 42  ,11,'External' UNION ALL
SELECT 'Project 4', 57  ,5,'Internal' UNION ALL
SELECT 'Project 5', 22  ,77,'Internal' UNION ALL
SELECT 'Project 5', 17  ,9,'External' 
)
SELECT Project,
        sum(ISNULL([Internal],0)) AS [Internal],
        sum(ISNULL([External],0)) AS [External],
        sum(ISNULL([Internal2],0)) AS [InternalSPC],
        sum(ISNULL([External2],0)) AS [ExternalSPC]
FROM
(
SELECT Project,
        Cost,
        spc,
        CostType,
        CostType+'2' as CostType2
from CTE
)AS SRC
PIVOT
(
SUM(Cost) FOR CostType IN ([Internal],[External])
)
AS PVT

PIVOT
(
SUM(spc) FOR CostType2 IN ([Internal2],[External2])
)
AS PVT
group by Project

答案 1 :(得分:1)

我首先要unpivot数据,以便所有值都在一个列中,合并另一对列,以便我们有不同的名称,然后可以应用单个PIVOT:< / p>

;WITH CTE(Project,Cost,spc,CostType)
AS
(
SELECT 'Project 1', 100 ,103,'Internal' UNION ALL
SELECT 'Project 1', 12  ,15,'External' UNION ALL
SELECT 'Project 2', 45  ,22,'Internal' UNION ALL
SELECT 'Project 2', 2   ,37,'External' UNION ALL
SELECT 'Project 2', 33  ,46,'Internal' UNION ALL
SELECT 'Project 3', 42  ,11,'External' UNION ALL
SELECT 'Project 4', 57  ,5,'Internal' UNION ALL
SELECT 'Project 5', 22  ,77,'Internal' UNION ALL
SELECT 'Project 5', 17  ,9,'External' 
), Combined as (
select
    Project, CostType + Nature as Title, Value
from
    CTE
        unpivot (Value for Nature in (Cost,spc)) u
)
select
 Project,
        ISNULL([InternalCost],0) AS [Internal],
        ISNULL([ExternalCost],0) AS [External],
        ISNULL([InternalSpc],0) AS [InternalSPC],
        ISNULL([ExternalSpc],0) AS [ExternalSPC]
from
    Combined
        pivot (SUM(Value) for Title in 
              (InternalCost,ExternalCost,InternalSpc,ExternalSpc)) u

您的尝试不起作用的主要原因是PIVOT应用了非显而易见的分组 1 。因此,在您的第一个PIVOT中,Spc列中明显不同的值意味着您不仅会为每个Project值生成一个输出行。

因此,我通常会尝试将这类查询减少为仅应用仅与感兴趣的列一起使用的PIVOT


1 我的意思是,我更愿意为GROUP BY使用显式的PIVOT语法,这样可以很明显地将哪些列用于分组,而不是它是“ PIVOT子句中未提及的当前结果集中的所有列”。但是即使使用这样的语法,它也会突出显示(如果您可以按Project分组)Spc在第二个PIVOT中不再可用。

答案 2 :(得分:1)

我将通过使用单个有条件聚集查询来做到这一点:

select Project, 
       sum(case when costtype = 'Internal' then Cost else 0 end) as Internal,
       sum(case when costtype = 'External' then Cost else 0 end) as External,
       sum(case when costtype = 'Internal' then spc else 0 end) as InternalSPC ,
       sum(case when costtype = 'External' then spc else 0 end) as ExternalSPC 
from cte c
group by Project;