SQL查询动态透视

SQL查询动态透视,sql,sql-server,tsql,Sql,Sql Server,Tsql,可能重复: 我有以下结构的临时表: MONTH ID CNT ----- ----------- --- 4 TOTAL_COUNT 214 5 TOTAL_COUNT 23 6 TOTAL_COUNT 23 4 FUNC_COUNT 47 5 FUNC_COUNT 5 6 FUNC_COUNT 5 4 INDIL_COUNT 167 5 INDIL_COUNT 18

可能重复:

我有以下结构的临时表:

MONTH  ID           CNT
-----  -----------  ---
4      TOTAL_COUNT  214
5      TOTAL_COUNT  23
6      TOTAL_COUNT  23
4      FUNC_COUNT   47
5      FUNC_COUNT   5
6      FUNC_COUNT   5
4      INDIL_COUNT  167
5      INDIL_COUNT  18
6      INDIL_COUNT  18
如何在该表中获得每月的数据透视,如:

ID           APRIL  MAY  JUNE 
-----------  -----  ---  ----
TOTAL_COUNT  214    23   23
FUNC_COUNT   47     5    5
INDIL_COUNT  167    18   18

请考虑这个表格格式。我发布这种格式有点混乱。

我将把月份整数到月份名称的转换留给您,但这将为您执行透视

declare @t table
( [month] int, [id] nvarchar(20), [cnt] int )

insert @t values (4,'TOTAL_COUNT',214)
insert @t values (5,'TOTAL_COUNT',23)
insert @t values (6,'TOTAL_COUNT',23)
insert @t values (4,'FUNC_COUNT',47)
insert @t values (5,'FUNC_COUNT',5)
insert @t values (6,'FUNC_COUNT',5)
insert @t values (4,'INDIL_COUNT',167)
insert @t values (5,'INDIL_COUNT',18)
insert @t values (6,'INDIL_COUNT',18)

SELECT 
    [id], [4], [5], [6]
FROM
    (SELECT [month], [id], [cnt] FROM @t) src
PIVOT
    (SUM([cnt]) FOR [month] IN ([4], [5], [6])) p

我将把月份整数到月份名称的转换留给您,但这将为您执行透视

declare @t table
( [month] int, [id] nvarchar(20), [cnt] int )

insert @t values (4,'TOTAL_COUNT',214)
insert @t values (5,'TOTAL_COUNT',23)
insert @t values (6,'TOTAL_COUNT',23)
insert @t values (4,'FUNC_COUNT',47)
insert @t values (5,'FUNC_COUNT',5)
insert @t values (6,'FUNC_COUNT',5)
insert @t values (4,'INDIL_COUNT',167)
insert @t values (5,'INDIL_COUNT',18)
insert @t values (6,'INDIL_COUNT',18)

SELECT 
    [id], [4], [5], [6]
FROM
    (SELECT [month], [id], [cnt] FROM @t) src
PIVOT
    (SUM([cnt]) FOR [month] IN ([4], [5], [6])) p

虽然您可以使用一个静态轴心点——一个您可以硬编码月份的轴心点。在评论中,您表示月份数可能未知,如果是这种情况,则您将希望使用动态透视生成月份列表。使用动态轴心使您能够灵活地在运行它之前不知道所需的列

create table t
( 
    [month] int, 
    [id] nvarchar(20), 
    [cnt] int 
)

insert t values (4,'TOTAL_COUNT',214)
insert t values (5,'TOTAL_COUNT',23)
insert t values (6,'TOTAL_COUNT',23)
insert t values (4,'FUNC_COUNT',47)
insert t values (5,'FUNC_COUNT',5)
insert t values (6,'FUNC_COUNT',5)
insert t values (4,'INDIL_COUNT',167)
insert t values (5,'INDIL_COUNT',18)
insert t values (6,'INDIL_COUNT',18)

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX);

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(month) 
            FROM t 
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT id, ' + @cols + ' from 
            (
                select month, id, cnt
                from t
           ) x
            pivot 
            (
                 sum(cnt)
                for month in (' + @cols + ')
            ) p '


execute(@query)

drop table t
结果将是:


而您可以使用一个静态轴心点——一个您可以硬编码月份的轴心点。在评论中,您表示月份数可能未知,如果是这种情况,则您将希望使用动态透视生成月份列表。使用动态轴心使您能够灵活地在运行它之前不知道所需的列

create table t
( 
    [month] int, 
    [id] nvarchar(20), 
    [cnt] int 
)

insert t values (4,'TOTAL_COUNT',214)
insert t values (5,'TOTAL_COUNT',23)
insert t values (6,'TOTAL_COUNT',23)
insert t values (4,'FUNC_COUNT',47)
insert t values (5,'FUNC_COUNT',5)
insert t values (6,'FUNC_COUNT',5)
insert t values (4,'INDIL_COUNT',167)
insert t values (5,'INDIL_COUNT',18)
insert t values (6,'INDIL_COUNT',18)

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX);

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(month) 
            FROM t 
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT id, ' + @cols + ' from 
            (
                select month, id, cnt
                from t
           ) x
            pivot 
            (
                 sum(cnt)
                for month in (' + @cols + ')
            ) p '


execute(@query)

drop table t
结果将是:


再想想,你只需要选择[id],[4]作为[April],[5]作为[May],[6]作为[June]!感谢您的回答,我希望得到类似的答案,但是[MONTH]字段是灵活的,因此Select语句总是给出恒定的结果,月份值可以是1月、2月和3月。如何生成这些动态枢轴是一件复杂得多的事情。如果您对PIVOT没有信心,那么我强烈建议您不要使用动态PIVOT—它涉及动态SQL,是一个非常令人头痛的问题。通常这是一项报告或可视化要求,因此我建议您在演示层中进行这种格式设置。对我来说,这似乎是一个有点复杂的解决方案。我认为我只需要在我的SSRS报告中进行管理。尽管@KrikIf您使用的是SSRS,但还是更倾向于使用列组进行设置。再想一想,您只需
选择[id],[4]作为[April],[5]作为[May],[6]作为[June]
!感谢您的回答,我希望得到类似的答案,但是[MONTH]字段是灵活的,因此Select语句总是给出恒定的结果,月份值可以是1月、2月和3月。如何生成这些动态枢轴是一件复杂得多的事情。如果您对PIVOT没有信心,那么我强烈建议您不要使用动态PIVOT—它涉及动态SQL,是一个非常令人头痛的问题。通常这是一项报告或可视化要求,因此我建议您在演示层中执行此格式设置。对我来说,这似乎是一个有点复杂的解决方案。我认为我只需要在我的SSRS报告中管理此问题。尽管@KrikIf您正在使用SSRS,但还是更倾向于使用列组执行此操作。非常感谢@Bluefeet。刚刚解决了问题。非常感谢@Bluefeet。它刚刚解决了问题。