使用SQL pivot的行/列合计汇总表

使用SQL pivot的行/列合计汇总表,sql,sql-server,pivot,pivot-table,Sql,Sql Server,Pivot,Pivot Table,我需要SQL的帮助来生成计算了行/列总数的数据透视表。我有两个表,如下所示 Table ProbCat ============== probcat | probdesc 1 minor 2 high 3 showstopper Table ProbSummary =================== prodcat | noofproblems | stage 1 5 Dev 2

我需要SQL的帮助来生成计算了行/列总数的数据透视表。我有两个表,如下所示

Table ProbCat
==============
probcat | probdesc
1         minor
2         high
3         showstopper


Table ProbSummary
===================
prodcat | noofproblems | stage
1          5             Dev 
2          1             Dev 
3          6             QA
3          6             Prod
我想生成一个包含行/列总百分比的透视表,如下所示。我尝试了“pivot”和“groupby”的组合,但无法准确获得行和列的总数

问题摘要视图: 除了底部的
总计
行之外,这应该提供您所需的内容


除了底部的
总计
行之外,这应该是您所需要的。

这里有一个
透视
查询,您可以使用它。。您的示例在一个表中有
prodcat
,在另一个表中有
probcat
。。不确定这是否是第二个表中的输入错误,所以我只对这两个表使用了
probcat
。应该很容易修复,因为它会给你一个错误

;
WITH ProbCatSummary AS
(
    SELECT  pc.probcat,
            pc.probdesc,
            SUM(ps.noofproblems) AS noofproblems
    FROM    ProbCat pc 
            JOIN ProbSummary ps ON pc.probcat = ps.probcat
    GROUP BY pc.probcat,
            pc.probdesc
)
SELECT  p.*,  
        [Total (%)] =   CONVERT(VARCHAR,[Dev] + [QA] + [Prod]) 
                        + ' (' + CONVERT(VARCHAR,  
                                    CAST(ROUND((([Dev] + [QA] + [Prod]) * 100.0 / SUM(ps.noofproblems) OVER()),2) AS DECIMAL(8,2))
                                ) 
                        + ')'
FROM (
    SELECT  probcat, probdesc, ISNULL([Dev],0)[Dev], ISNULL([QA],0)[QA], ISNULL([Prod],0)[Prod]
    FROM    (SELECT pc.probcat, probdesc, stage, noofproblems
            FROM    ProbCat pc 
                    JOIN ProbSummary ps ON pc.probcat = ps.probcat) AS s
    PIVOT (SUM(noofproblems) FOR stage IN ([Dev], [QA], [Prod])) AS p
) p JOIN ProbCatSummary ps ON p.probcat = ps.probcat

这里有一个可以使用的
PIVOT
查询。。您的示例在一个表中有
prodcat
,在另一个表中有
probcat
。。不确定这是否是第二个表中的输入错误,所以我只对这两个表使用了
probcat
。应该很容易修复,因为它会给你一个错误

;
WITH ProbCatSummary AS
(
    SELECT  pc.probcat,
            pc.probdesc,
            SUM(ps.noofproblems) AS noofproblems
    FROM    ProbCat pc 
            JOIN ProbSummary ps ON pc.probcat = ps.probcat
    GROUP BY pc.probcat,
            pc.probdesc
)
SELECT  p.*,  
        [Total (%)] =   CONVERT(VARCHAR,[Dev] + [QA] + [Prod]) 
                        + ' (' + CONVERT(VARCHAR,  
                                    CAST(ROUND((([Dev] + [QA] + [Prod]) * 100.0 / SUM(ps.noofproblems) OVER()),2) AS DECIMAL(8,2))
                                ) 
                        + ')'
FROM (
    SELECT  probcat, probdesc, ISNULL([Dev],0)[Dev], ISNULL([QA],0)[QA], ISNULL([Prod],0)[Prod]
    FROM    (SELECT pc.probcat, probdesc, stage, noofproblems
            FROM    ProbCat pc 
                    JOIN ProbSummary ps ON pc.probcat = ps.probcat) AS s
    PIVOT (SUM(noofproblems) FOR stage IN ([Dev], [QA], [Prod])) AS p
) p JOIN ProbCatSummary ps ON p.probcat = ps.probcat

正如前面提到的其他内容一样,您的汇总/总计计算应该在表示层上完成。但我想让你的输出减去最后一行:

;WITH Q1
AS (
    SELECT pvt.probcat
        ,pvt.probdesc
        ,ISNULL(pvt.[Dev], 0) AS 'Dev'
        ,ISNULL(pvt.[QA], 0) AS 'QA'
        ,ISNULL(pvt.[Prod], 0) AS 'Prod'
    FROM (
        SELECT pc.probcat
            ,pc.probdesc
            ,ps.noofproblems
            ,ps.stage
        FROM Probcat pc
        LEFT JOIN ProbSummary ps ON pc.probcat = ps.probcat
        ) t
    PIVOT(max(noofproblems) FOR stage IN (
                [Dev]
                ,[QA]
                ,[Prod]
                )) pvt
    ),
q2 as
(SELECT q1.*
    ,sum(q1.Dev + q1.QA + q1.Prod) AS Total
FROM q1

GROUP BY q1.probcat
    ,q1.probdesc
    ,q1.Dev
    ,q1.QA
    ,q1.Prod
)
select q2.probcat
    ,q2.probdesc
    ,q2.Dev
    ,q2.QA
    ,q2.Prod
    ,cast(q2.Total as varchar(10)) + ' (' +
    cast(cast((cast(q2.Total as decimal(5,2))/cast(d.CrossSum as decimal(5,2)))*100 
    as decimal(5,2)) as varchar(10))
    + '% )' as FinalTotal
    from q2
  CROSS APPLY (
    SELECT sum(q1.Dev + q1.QA + q1.Prod) AS CrossSum
    FROM q1
    ) d  
ORDER BY q2.probcat

就像前面提到的其他内容一样,您的汇总/总计计算应该在表示层上完成。但我想让你的输出减去最后一行:

;WITH Q1
AS (
    SELECT pvt.probcat
        ,pvt.probdesc
        ,ISNULL(pvt.[Dev], 0) AS 'Dev'
        ,ISNULL(pvt.[QA], 0) AS 'QA'
        ,ISNULL(pvt.[Prod], 0) AS 'Prod'
    FROM (
        SELECT pc.probcat
            ,pc.probdesc
            ,ps.noofproblems
            ,ps.stage
        FROM Probcat pc
        LEFT JOIN ProbSummary ps ON pc.probcat = ps.probcat
        ) t
    PIVOT(max(noofproblems) FOR stage IN (
                [Dev]
                ,[QA]
                ,[Prod]
                )) pvt
    ),
q2 as
(SELECT q1.*
    ,sum(q1.Dev + q1.QA + q1.Prod) AS Total
FROM q1

GROUP BY q1.probcat
    ,q1.probdesc
    ,q1.Dev
    ,q1.QA
    ,q1.Prod
)
select q2.probcat
    ,q2.probdesc
    ,q2.Dev
    ,q2.QA
    ,q2.Prod
    ,cast(q2.Total as varchar(10)) + ' (' +
    cast(cast((cast(q2.Total as decimal(5,2))/cast(d.CrossSum as decimal(5,2)))*100 
    as decimal(5,2)) as varchar(10))
    + '% )' as FinalTotal
    from q2
  CROSS APPLY (
    SELECT sum(q1.Dev + q1.QA + q1.Prod) AS CrossSum
    FROM q1
    ) d  
ORDER BY q2.probcat

包含总计的行应留给表示层。不是sql server。我同意……我一直在玩这个游戏,与在表示层计算行和列总数的简单程度相比,要实现您想要的是非常复杂的。感谢您的反馈,我能够通过混合使用查询和表示层来实现它,以计算列的总百分比。包含总百分比的行应该留给表示层。不是sql server。我同意……我一直在玩这个游戏,与在表示层计算行和列总数的简单程度相比,要实现您想要的是非常复杂的。感谢您的反馈,我能够通过查询和表示层的混合来实现它,用于计算列总百分比提供查询的感谢,我能够使用所有响应感谢提供查询的感谢,我能够使用所有响应感谢提供查询的感谢,我能够解决所有问题感谢提供查询,我能够解决所有问题