分组函数中带有汇总和案例语句的数据透视表

Posted

技术标签:

【中文标题】分组函数中带有汇总和案例语句的数据透视表【英文标题】:Pivot table with rollup and case statement in the Grouping function 【发布时间】:2012-04-11 04:32:19 【问题描述】:

我正在尝试在分组函数中创建一个带有汇总和 case 语句的数据透视表。当不需要更改数据透视的列部分中的数据时,我的查询效果很好,

他就是一个例子。

http://sqlfiddle.com/#!3/3143e/2

但是当我需要在列部分中有一个 case 语句时,它会搞砸。例如其中一列需要返回

“1 of 3” if someone voted in one of three elections, 
“2 of 3” if someone voted in two of three elections, 
“3 of 3” if someone voted in three of three elections,

这是case语句

CAST( (CASE WHEN election1 IS NOT NULL THEN 1 ELSE 0 END)
       +(CASE WHEN election2 IS NOT NULL THEN 1 ELSE 0 END)
       +(CASE WHEN election3 IS NOT NULL THEN 1 ELSE 0 END) AS CHAR(1)) + '-3' as election

我需要帮助弄清楚如何将此 case 语句放入 Grouping() 函数中,或者可能有其他方法可以做到这一点。我试过这样的事情

http://sqlfiddle.com/#!3/3143e/3

当然它没有用。 这就是最终支点的样子

1 http://img842.imageshack.us/img842/6884/84834931.jpg

提前致谢

【问题讨论】:

【参考方案1】:

所以我有一个建议给你。我以另一种方式做到了,但它确实有效。

测试数据

create table test4(city nvarchar(10), race nvarchar(30), sex nvarchar(10), age int, type nvarchar(30),election1 nvarchar(30), election2 nvarchar(30), election3 nvarchar(30),)
insert into test4 values ('Austin',  'African-American', 'male', 21, 'gv','G10','G08','G06')
insert into test4 values ('Austin',  'Asian', 'female', 22,'AV',null,'G08','G06')
insert into test4 values ('Austin',  'Caucasian', 'male', 23,'BV','G10',null,null)
insert into test4 values ('Austin',  'Hispanic', 'female', 24,'AV','G10','G08','G06')
insert into test4 values ('Austin',  'African-American', 'Unknown', 25,'CV','G10','G08',null)
insert into test4 values ('Austin',  'Asian', 'male', 26,'gv',null,'G08','G06')
insert into test4 values ('Austin',  'Caucasian', 'female', 27,'CV',null,'G08','G06')
insert into test4 values ('Austin',  'Hispanic', 'Unknown', 28,'AV',null,'G08','G06')
insert into test4 values ('Austin',  'Asian', 'male', 29,'BV','G10',null,'G06')
insert into test4 values ('Austin',  'Caucasian', 'female', 31,'gv','G10',null,'G06')
insert into test4 values ('Dallas',  'Hispanic', 'Unknown', 32,'BV','G10',null,'G06')
insert into test4 values ('Dallas',  'African-American', 'male', 33,'gv','G10',null,'G06')
insert into test4 values ('Dallas',  'Asian', 'female', 34,'BV',null,'G08','G06')
insert into test4 values ('Dallas',  'Caucasian', 'Unknown', 35,'AV',null,null,null)
insert into test4 values ('Dallas',  'Hispanic', 'male', 500,'AV',null,'G08',null)
insert into test4 values ('Dallas',  'African-American', 'female', 36,'AV','G10',null,'G06')
insert into test4 values ('Dallas',  'Asian', 'Unknown', 37,'CV','G10','G08',null)
insert into test4 values ('Dallas',  'Caucasian', 'male', 38,'CV',null,null,null)
insert into test4 values ('Dallas',  'Hispanic', 'female', 39,'gv','G10','G08','G06')
insert into test4 values ('Dallas',  'African-American', 'Unknown', 41,'CV',null,'G08','G06')
insert into test4 values ('Houston',  'Asian', 'male', 42,'BV',null,'G08',null)
insert into test4 values ('Houston',  'Caucasian', 'female', 43,'CV','G10',null,'G06')
insert into test4 values ('Houston',  'Hispanic', 'Unknown', 44,'BV','G10',null,'G06')
insert into test4 values ('Houston',  'African-American', 'male', 45,'CV',null,'G08','G06')
insert into test4 values ('Houston',  'Asian', 'female', 46,'CV','G10','G08','G06')
insert into test4 values ('Houston',  'Caucasian', 'Unknown', 47,'gv',null,null,null)
insert into test4 values ('Houston',  'Hispanic', 'male', 48,'AV','G10','G08',null)
insert into test4 values ('Houston',  'African-American', 'female', 49,'gv','G10',null,'G06')
insert into test4 values ('Houston',  'Asian', 'Unknown', 51,'BV',null,'G08',null)
insert into test4 values ('Houston',  'Caucasian', 'male', 52,'AV',null,'G08','G06');

PIVOTUNION ALL

;WITH PivotTable
AS
(
    SELECT
        pvt.city,
        pvt.sex,
        pvt.election,
        ISNULL(pvt.[20_30_Af],0) AS [20_30_Af],
        ISNULL(pvt.[20_30_As],0) AS [20_30_As],
        ISNULL(pvt.[20_30_C],0) AS [20_30_C],
        ISNULL(pvt.[20_30_H],0) AS [20_30_H],
        ISNULL(pvt.[30_40_Af],0) AS [30_40_Af],
        ISNULL(pvt.[30_40_As],0) AS [30_40_As],
        ISNULL(pvt.[30_40_C],0) AS [30_40_C],
        ISNULL(pvt.[30_40_H],0) AS [30_40_H],
        ISNULL(pvt.[40_50_Af],0) AS [40_50_Af],
        ISNULL(pvt.[40_50_As],0) AS [40_50_As],
        ISNULL(pvt.[40_50_C],0) AS [40_50_C],
        ISNULL(pvt.[40_50_H],0) AS [40_50_H]
    FROM
    (
    SELECT
        (
        case 
            when race = 'African-American' and age between 21 and 30 
            then '20_30_Af' 
            when race = 'Asian' and age between 21 and 30
            then '20_30_As'
            when race = 'Caucasian' and age between 21 and 30
            then '20_30_C'
            when race = 'Hispanic' and age between 21 and 30
            then '20_30_H'
            when race = 'African-American' and age between 31 and 40
            then '30_40_Af'
            when race = 'Asian' and age between 31 and 40
            then '30_40_As'
            when race = 'Caucasian' and age between 31 and 40
            then '30_40_C'
            when race = 'Hispanic' and age between 31 and 40
            then '30_40_H'
            when race = 'African-American' and age between 41 and 50
            then '40_50_Af'
            when race = 'Asian' and age between 41 and 50
            then '40_50_As'
            when race = 'Caucasian' and age between 41 and 50
            then '40_50_C'
            when race = 'Hispanic' and age between 41 and 50
            then '40_50_H'
        end
        ) AS pivotText,
        1 as pivotNbr,
        test4.city,
        test4.sex,
        CAST( (CASE WHEN election1 IS NOT NULL THEN 1 ELSE 0 END)
           +(CASE WHEN election2 IS NOT NULL THEN 1 ELSE 0 END)
           +(CASE WHEN election3 IS NOT NULL THEN 1 ELSE 0 END) AS CHAR(1)) 
            + '-3' as election
    FROM
        test4
    ) AS p
    PIVOT
    (
        SUM(pivotNbr)
        FOR pivotText IN([20_30_Af],[20_30_As],
            [20_30_C],[20_30_H],[30_40_Af],
            [30_40_As],[30_40_C],[30_40_H],
            [40_50_Af],[40_50_As],[40_50_C],[40_50_H])
    ) AS pvt
)
SELECT
    PivotTable.city,
    PivotTable.sex,
    PivotTable.election,
    PivotTable.[20_30_Af],
    PivotTable.[20_30_As],
    PivotTable.[20_30_C],
    PivotTable.[20_30_H],
    PivotTable.[30_40_Af],
    PivotTable.[30_40_As],
    PivotTable.[30_40_C],
    PivotTable.[30_40_H],
    PivotTable.[40_50_Af],
    PivotTable.[40_50_As],
    PivotTable.[40_50_C],
    PivotTable.[40_50_H],
    (
        PivotTable.[20_30_Af]+
        PivotTable.[20_30_As]+
        PivotTable.[20_30_C]+
        PivotTable.[20_30_H]+
        PivotTable.[30_40_Af]+
        PivotTable.[30_40_As]+
        PivotTable.[30_40_C]+
        PivotTable.[30_40_H]+
        PivotTable.[40_50_Af]+
        PivotTable.[40_50_As]+
        PivotTable.[40_50_C]+
        PivotTable.[40_50_H]
    ) AS Total,
    null as isGrandTotal,
    2 AS sortOrder
FROM
    PivotTable
UNION ALL
SELECT
    PivotTable.city,
    '' AS sex,
    '' AS election,
    SUM(PivotTable.[20_30_Af]) AS [20_30_Af],
    SUM(PivotTable.[20_30_As]) AS [20_30_As],
    SUM(PivotTable.[20_30_C]) AS [20_30_C],
    SUM(PivotTable.[20_30_H]) AS [20_30_H],
    SUM(PivotTable.[30_40_Af]) AS [30_40_Af],
    SUM(PivotTable.[30_40_As]) AS [30_40_As],
    SUM(PivotTable.[30_40_C]) AS [30_40_C],
    SUM(PivotTable.[30_40_H]) AS [30_40_H],
    SUM(PivotTable.[40_50_Af]) AS [40_50_Af],
    SUM(PivotTable.[40_50_As]) AS [40_50_As],
    SUM(PivotTable.[40_50_C]) AS [40_50_C],
    SUM(PivotTable.[40_50_H]) AS [40_50_H],
    SUM(
        PivotTable.[20_30_Af]+
        PivotTable.[20_30_As]+
        PivotTable.[20_30_C]+
        PivotTable.[20_30_H]+
        PivotTable.[30_40_Af]+
        PivotTable.[30_40_As]+
        PivotTable.[30_40_C]+
        PivotTable.[30_40_H]+
        PivotTable.[40_50_Af]+
        PivotTable.[40_50_As]+
        PivotTable.[40_50_C]+
        PivotTable.[40_50_H]
    ) AS Total,
    null as isGrandTotal,
    1 AS sortOrder
FROM
    PivotTable
GROUP BY 
    PivotTable.city
UNION ALL
SELECT
    'Grand Total' AS city,
    '' AS sex,
    '' AS election,
    SUM(PivotTable.[20_30_Af]) AS [20_30_Af],
    SUM(PivotTable.[20_30_As]) AS [20_30_As],
    SUM(PivotTable.[20_30_C]) AS [20_30_C],
    SUM(PivotTable.[20_30_H]) AS [20_30_H],
    SUM(PivotTable.[30_40_Af]) AS [30_40_Af],
    SUM(PivotTable.[30_40_As]) AS [30_40_As],
    SUM(PivotTable.[30_40_C]) AS [30_40_C],
    SUM(PivotTable.[30_40_H]) AS [30_40_H],
    SUM(PivotTable.[40_50_Af]) AS [40_50_Af],
    SUM(PivotTable.[40_50_As]) AS [40_50_As],
    SUM(PivotTable.[40_50_C]) AS [40_50_C],
    SUM(PivotTable.[40_50_H]) AS [40_50_H],
    SUM(
        PivotTable.[20_30_Af]+
        PivotTable.[20_30_As]+
        PivotTable.[20_30_C]+
        PivotTable.[20_30_H]+
        PivotTable.[30_40_Af]+
        PivotTable.[30_40_As]+
        PivotTable.[30_40_C]+
        PivotTable.[30_40_H]+
        PivotTable.[40_50_Af]+
        PivotTable.[40_50_As]+
        PivotTable.[40_50_C]+
        PivotTable.[40_50_H]
    ) AS Total,
    1 as isGrandTotal,
    3 AS sortOrder
FROM
    PivotTable
ORDER BY 
    isGrandTotal,
    city,
    sortOrder

【讨论】:

这肯定行得通,但我已经用这种方式构建了其余的枢轴。我昨晚想了想,意识到我可以创建另一个临时表,然后从该表中进行分组,它就可以工作了。 sqlfiddle.com/#!3/3143e/19 我会将您的答案标记为正确,因为它也可以工作。感谢您的帮助。 没问题...如果您认为答案很好,请记得点赞。它给了我们所有温暖模糊的感觉:P

以上是关于分组函数中带有汇总和案例语句的数据透视表的主要内容,如果未能解决你的问题,请参考以下文章

多维透视表 - 矩表实现商品销售对比统计

分类汇总和数据透视表的优缺点

多维透视表 - 矩表实现商品销售对比统计

Excel 请问资料透视表如何去掉汇总行

快速取消数据透视表的分类汇总行和总计行

列子句中带有子查询的 MS SQL Server 数据透视表