SQL Pivot 每行创建 2 列

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

我有一张看起来像这样的桌子:

日期 姓名 实际 目标
2023-03-14 鲍勃 15 15
2023-03-14 吉姆 9 5
2023-03-14 史蒂夫 10 9
2023-03-15 鲍勃 11 11
2023-03-15 吉姆 16 16
2023-03-15 史蒂夫 5 12

名称列并不总是相同,具体取决于谁在工作,因此枢轴必须是动态的。 我希望表格看起来像这样:

日期 鲍勃_实际 鲍勃_目标 吉姆_实际 吉姆_目标 史蒂夫_实际 史蒂夫_目标
2023-03-14 15 15 9 5 10 9
2023-03-15 11 11 16 16 5 12

如果我只是动态地围绕目标旋转,我就能够获得所需的结果,但我不知道如何同时旋转目标和实际

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

select @cols = STUFF((SELECT ',' + QUOTENAME(Name) 
                    from yt
                    group by Name
                    order by Name
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT Date,' + @cols + ' from 
             (
                select Date, Name, Target
                from yt
            ) x
            pivot 
            (
                sum(Target)
                for Name in (' + @cols + ')
            ) p '

execute(@query);

我使用上面的代码让它只适用于目标,但不知道如何添加实际的

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

不要使用枢轴,它们不够灵活,尝试条件聚合:

SELECT  *
INTO #yt
FROM    (
    VALUES  (N'2023-03-14', N'Bob', 15, 15)
    ,   (N'2023-03-14', N'Jim', 9, 5)
    ,   (N'2023-03-14', N'Steve', 10, 9)
    ,   (N'2023-03-15', N'Bob', 11, 11)
    ,   (N'2023-03-15', N'Jim', 16, 16)
    ,   (N'2023-03-15', N'Steve', 5, 12)
) t (Date,Name,Actual,Target)

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

SELECT  @cols = (   
    SELECT  '
    ,   SUM(case when name = ' + QUOTENAME(Name, '''') + ' then Actual END) AS ' + QUOTENAME(Name + '_Actual') + N'
    ,   SUM(case when name = ' + QUOTENAME(Name, '''') + ' then Target END) AS ' + QUOTENAME(Name + '_Targer')
    FROM    #yt
    GROUP BY Name
    ORDER BY Name
    FOR XML PATH(''), TYPE
            ).value('text()[1]', 'NVARCHAR(MAX)') 

SET @query = '
    SELECT  Date' + @cols + '
    FROM    #yt
    GROUP BY Date
            '
EXEC(@query);

这样,您可以更灵活地处理列名称和值。 SUM(CASE WHEN ...) 是条件聚合部分,用于获取所需的值并将它们放置在正确的列中。

© www.soinside.com 2019 - 2024. All rights reserved.