【问题标题】:SQL Server PIVOT with multiple X-axis columns具有多个 X 轴列的 SQL Server PIVOT
【发布时间】:2012-10-15 21:10:02
【问题描述】:

以下面的数据为例:

Payroll Forname Surname Month   Year    Amount
0000001 James   Bond    3       2011    144.00
0000001 James   Bond    6       2012    672.00
0000001 James   Bond    7       2012    240.00
0000001 James   Bond    8       2012    1744.50
0000002 Elvis   Presley 3       2011    1491.00
0000002 Elvis   Presley 6       2012    189.00
0000002 Elvis   Presley 7       2012    1816.50
0000002 Elvis   Presley 8       2012    1383.00

我将如何在年 + 月(例如:201210)上对此进行 PIVOT,但将工资单、姓名和姓氏保留为单独的列,例如,上面将变为:

Payroll Forename    Surname 201103  201206  201207  201208
0000001 James       Bond    144.00  672.00  240.00  1744.50
0000002 Elvis       Presley 1491.00 189.00  1816.50 1383.00

我假设因为年 + 月的名称可以改变,那么我将需要使用动态 SQL + PIVOT - 我尝试过但甚至无法解析代码,没关系运行 - 任何帮助将不胜感激!

编辑:到目前为止我所拥有的:

    INSERT  INTO #tbl_RawDateBuffer
            ( PayrollNumber ,
              Surname ,
              Forename ,
              [Month] ,
              [Year] ,
              AmountPayable
            )
            SELECT  PayrollNumber ,
                    Surname ,
                    Forename ,
                    [Month] ,
                    [Year] ,
                    AmountPayable
            FROM    RawData
            WHERE   [Max] > 1500


DECLARE @Columns AS NVARCHAR(MAX)
DECLARE @StrSQL AS NVARCHAR(MAX) 

SET @Columns = STUFF((SELECT DISTINCT
                                ',' + QUOTENAME(CONVERT(VARCHAR(4), c.[Year]) + RIGHT('00' + CONVERT(VARCHAR(2), c.[Month]), 2))
                      FROM      #tbl_RawDateBuffer c
    FOR              XML PATH('') ,
                         TYPE 
            ).value('.', 'NVARCHAR(MAX)'), 1, 1, '') 

SET @StrSQL = 'SELECT PayrollNumber, ' + @Columns + ' from 
            (
                select PayrollNumber
                    , CONVERT(VARCHAR(4), [Year]) + RIGHT(''00'' + CONVERT(VARCHAR(2), [Month]), 2) dt
                from #tbl_RawDateBuffer
           ) x
            pivot 
            (
                sum(AmountPayable)
                for dt in (' + @Columns + ')
            ) p '


EXECUTE(@StrSQL)

DROP TABLE #tbl_RawDateBuffer

【问题讨论】:

    标签: sql sql-server sql-server-2008 tsql pivot


    【解决方案1】:

    select payroll, forname,surname,[20113] as [201103], [20126] as [201206], [20127] as [201207], [20128] as [201208] 从 (选择工资单、姓名、姓氏、年+月作为 d、来自支点 1 的金额)向上 pivot(sum(up.Amount) for up.d in ([20113], [20126], [20127], [20128])) 作为 pvt

    【讨论】:

    • 有几个问题,OP 请求动态版本的解决方案。另外,您将年/月连接在一起,如果值是 int,这将不起作用。
    • int 可以转换成 nvarchar
    【解决方案2】:

    好的,正如你所说,你将需要动态 SQL,所以首先转到this link。阅读后,请尝试以下操作:

    评论后更新代码:

    DECLARE @cols AS NVARCHAR(MAX), @cols2 AS NVARCHAR(MAX), @query AS NVARCHAR(MAX);
    
    WITH CTE AS
    (
        SELECT *, CAST([Year] AS NVARCHAR(4))+RIGHT('00'+CAST([Month] AS NVARCHAR(2)),2) YearMonth
        FROM YourTable
    )
    
    SELECT @cols = STUFF((  SELECT DISTINCT ',' + QUOTENAME(YearMonth) 
                            FROM CTE 
                            FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,''),
           @cols2 = STUFF(( SELECT DISTINCT ',ISNULL(' + QUOTENAME(YearMonth) + ',0) AS ' + QUOTENAME(YearMonth)
                            FROM CTE 
                            FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'')
    
    
    SET @query = '
    SELECT Payroll, Forname, Surname, ' + @cols2 + '
    FROM (  SELECT  Payroll, Forname, Surname, 
                    CAST([Year] AS NVARCHAR(4))+RIGHT(''00''+CAST([Month] AS NVARCHAR(2)),2) YearMonth,
                    Amount
            FROM YourTable ) T
    PIVOT(SUM(Amount) FOR YearMonth IN ('+@cols+')) PT'
    
    EXEC(@Query)
    

    【讨论】:

    • 一个问题 - 有没有办法在动态列中使用 ISNULL 来返回 0?
    • @HeavenCore 好吧,这并不像看起来那么容易。我没有对其进行测试,但我更新了我的答案以尝试满足您的要求。让我知道它是否有效
    • @bluefeet 是的,我真的很偏执,因为我在写答案时会收到新的答案通知
    • 您修改后的 ISNULL 代码效果很好 - 干杯,这些天我会掌握 PIVOT 的窍门 :)
    猜你喜欢
    • 2018-06-28
    • 2011-03-15
    • 1970-01-01
    • 2020-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-17
    • 1970-01-01
    相关资源
    最近更新 更多