带有子类别的 SQL PIVOT

问题描述 投票:0回答:1

总结:我正在尝试使用 SQL PIVOT 将性别作为 AgeBand 的子类别(请注意,年龄带每个跨越两列)。我已经让 AgeBand 本身工作了(见下文),但不确定如何在 SQL PIVOT (SQL Server) 中添加第二个级别(性别)。

65-74 65-74 75-84 75-84
123 234 56 654
123 5345 456 76

我有一个 SQL 查询,它使用 PIVOT 从如下所示的表中获取数据:

年龄范围 性别 部分 代码 描述 百分比
亚特兰蒂斯 65-74 F 13.一般 F34 苹果 279 0.089
亚特兰蒂斯 65-74 M 13.一般 H84 橙色 166 0.053
亚特兰蒂斯 65-74 F 13.一般 W234 梨子 8 0.003
亚特兰蒂斯 75-84 M 13.一般 U7 李子 541 0.261
亚特兰蒂斯 65-74 M 13.一般 V467 桃子 2 0.001

...等等...

看起来像这样(基于年龄范围的计数和百分比):

部分 代码 描述 整体 整体 65-74 65-74 75-84 75-84 85+ 85+
- - - - % % % %
亚特兰蒂斯 13.一般 F34 苹果 876 5 74 3 96 1 9 2
亚特兰蒂斯 13.一般 H84 橙色 876 7 67 7 86 4 6 1
亚特兰蒂斯 13.一般 W234 梨子 95 4 76 4 135 6 8 1
亚特兰蒂斯 13.一般 U7 李子 986 7 23 7 5 3 8 2
亚特兰蒂斯 13.一般 V467 桃子 1011 4 65 9 43 6 6 1

...

执行此操作的 SQL 效果很好:

SELECT County, Section, MeasureCode, MeasureDesc
    , MAX(CASE WHEN theValue = 'Members' THEN CAST([Overall] as int) ELSE 0 END) as [Overall Members]
    , MAX(CASE WHEN theValue = 'Percent' THEN CAST([Overall] as decimal(10,2)) ELSE 0 END) as [Overall Percent]
    , MAX(CASE WHEN theValue = 'Members' THEN CAST([65-74] as int) ELSE 0 END) as [65-74 Members]
    , MAX(CASE WHEN theValue = 'Percent' THEN CAST([65-74] as decimal(10,2)) ELSE 0 END) as [65-74 Percent]
    
    , MAX(CASE WHEN theValue = 'Members' THEN CAST([75-84] as int) ELSE 0 END) as [75-84 Members]
    , MAX(CASE WHEN theValue = 'Percent' THEN CAST([75-84] as decimal(10,2)) ELSE 0 END) as [75-84 Percent]
    
    , MAX(CASE WHEN theValue = 'Members' THEN CAST([85+] as int) ELSE 0 END) as [85+ Members]
    , MAX(CASE WHEN theValue = 'Percent' THEN CAST([85+] as decimal(10,2)) ELSE 0 END) as [85+ Percent]
    
FROM (
        SELECT 'Members' as theValue
            , County, Section, MeasureCode, MeasureDesc
            , [Overall], [65-74], [75-84], [85+]
        FROM #cond a
        PIVOT(SUM(MemberCount)
            FOR AgeBand IN ([Overall], [Under 65], [65-74], [75-84], [85+])
            ) b

        UNION
        SELECT 'Percent' as theValue
            , County, Section, MeasureCode, MeasureDesc
            , [Overall], [65-74], [75-84], [85+]
        FROM #cond a
        PIVOT(MAX(PctTotal)
            FOR AgeBand IN ([Overall], [65-74], [75-84], [85+])
            ) c
    ) e
    
GROUP BY County, Section, MeasureCode, MeasureDesc
ORDER BY Section
    , MAX(CASE WHEN Section = '13. Another Section' THEN CAST(MeasureDesc as int)
                        WHEN theValue = 'Percent' THEN CAST([Overall] as decimal(10,2))
                        WHEN theValue = 'Members' THEN CAST([Overall] as decimal(10,2))
                        ELSE 0 
                END) DESC

正如您所看到的,在原始数据集中,有一个性别列。我想将其添加为 AgeBands 的子类别,以便它看起来像这样(添加颜色和边框以使其更清晰):

(请注意,每个年龄段部分现在都有女性和男性细分 - 抱歉,表格标记无法执行合并单元格,这将使这一点更加清晰)

部分 代码 描述 整体 整体 整体 整体 65-74 65-74 65-74 65-74 75-84 75-84 75-84 75-84 85+ 85+ 85+ 85+
- - - -
- - - - % % % % % % % %
亚特兰蒂斯 13.一般 F34 苹果 876 5 876 5 74 3 74 3 96 1 96 1 9 2 9 2
亚特兰蒂斯 13.一般 H84 橙色 876 7 876 7 67 7 67 7 86 4 86 4 6 1 6 1
亚特兰蒂斯 13.一般 W234 梨子 95 4 95 4 76 4 76 4 135 6 135 6 8 1 8 1
亚特兰蒂斯 13.一般 U7 李子 986 7 986 7 23 7 23 7 5 3 5 3 8 2 8 2
亚特兰蒂斯 13.一般 V467 桃子 1011 4 1011 4 65 9 65 9 43 6 43 6 6 1 6 1

但是,我完全不知道如何在 SQL 中实现这一点。有人能指出我正确的方向吗?

sql sql-server pivot
1个回答
0
投票

我想 SQL 结果不能有 2 个列标题。但是您可以在代码中添加几行,如下所示?

    SELECT County, Section, MeasureCode, MeasureDesc
    , MAX(CASE WHEN (theValue = 'Members' And MemberGender = 'F') THEN CAST([Overall] as int) ELSE 0 END) as [F_Overall Members]
    , MAX(CASE WHEN (theValue = 'Members' And MemberGender = 'M') THEN CAST([Overall] as int) ELSE 0 END) as [M_Overall Members]
    , MAX(CASE WHEN (theValue = 'Percent' And MemberGender = 'F') THEN CAST([Overall] as decimal(10,2)) ELSE 0 END) as [F_Overall Percent]
    , MAX(CASE WHEN (theValue = 'Percent' And MemberGender = 'M') THEN CAST([Overall] as decimal(10,2)) ELSE 0 END) as [M_Overall Percent]
    , MAX(CASE WHEN (theValue = 'Members' And MemberGender = 'F') THEN CAST([65-74] as int) ELSE 0 END) as [F_65-74 Members]
    , MAX(CASE WHEN (theValue = 'Members' And MemberGender = 'M') THEN CAST([65-74] as int) ELSE 0 END) as [M_65-74 Members]
    , MAX(CASE WHEN (theValue = 'Percent' And MemberGender = 'F') THEN CAST([65-74] as decimal(10,2)) ELSE 0 END) as [F_65-74 Percent]
    , MAX(CASE WHEN (theValue = 'Percent' And MemberGender = 'M') THEN CAST([65-74] as decimal(10,2)) ELSE 0 END) as [M_65-74 Percent]
    
    , MAX(CASE WHEN (theValue = 'Members' And MemberGender = 'F') THEN CAST([75-84] as int) ELSE 0 END) as [F_75-84 Members]
    , MAX(CASE WHEN (theValue = 'Members' And MemberGender = 'M') THEN CAST([75-84] as int) ELSE 0 END) as [M_75-84 Members]
    , MAX(CASE WHEN (theValue = 'Percent' And MemberGender = 'F') THEN CAST([75-84] as decimal(10,2)) ELSE 0 END) as [F_75-84 Percent]
    , MAX(CASE WHEN (theValue = 'Percent' And MemberGender = 'M') THEN CAST([75-84] as decimal(10,2)) ELSE 0 END) as [M_75-84 Percent]
    
    , MAX(CASE WHEN (theValue = 'Members' And MemberGender = 'F') THEN CAST([85+] as int) ELSE 0 END) as [F_85+ Members]
    , MAX(CASE WHEN (theValue = 'Members' And MemberGender = 'M') THEN CAST([85+] as int) ELSE 0 END) as [M_85+ Members]
    , MAX(CASE WHEN (theValue = 'Percent' And MemberGender = 'F') THEN CAST([85+] as decimal(10,2)) ELSE 0 END) as [F_85+ Percent]
    , MAX(CASE WHEN (theValue = 'Percent' And MemberGender = 'M') THEN CAST([85+] as decimal(10,2)) ELSE 0 END) as [M_85+ Percent]
    
FROM (
        SELECT 'Members' as theValue
            , County, Section, MeasureCode, MeasureDesc, MemberGender
            , [Overall], [65-74], [75-84], [85+]
        FROM #cond a
        PIVOT(SUM(MemberCount)
            FOR AgeBand IN ([Overall], [Under 65], [65-74], [75-84], [85+])
            ) b

        UNION
        SELECT 'Percent' as theValue
            , County, Section, MeasureCode, MeasureDesc, MemberGender
            , [Overall], [65-74], [75-84], [85+]
        FROM #cond a
        PIVOT(MAX(PctTotal)
            FOR AgeBand IN ([Overall], [65-74], [75-84], [85+])
            ) c
    ) e
    
GROUP BY County, Section, MeasureCode, MeasureDesc, MemberGender
ORDER BY Section
    , MAX(CASE WHEN Section = '13. Another Section' THEN CAST(MeasureDesc as int)
                        WHEN theValue = 'Percent' THEN CAST([Overall] as decimal(10,2))
                        WHEN theValue = 'Members' THEN CAST([Overall] as decimal(10,2))
                        ELSE 0 
                END) DESC
© www.soinside.com 2019 - 2024. All rights reserved.