具有多个X轴列的SQL Server PIVOT

具有多个X轴列的SQL Server PIVOT,sql,sql-server,sql-server-2008,tsql,pivot,Sql,Sql Server,Sql Server 2008,Tsql,Pivot,以以下数据为例: 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 00000

以以下数据为例:

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)上突出这一点,但将工资单、姓名和姓氏保留为单独的列,例如,上述内容将变成:

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,所以首先转到。阅读此内容后,请尝试以下操作:

更新代码如下:


选择payroll,forname,姓氏[20113]为[201103],[20126]为[201206],[20127]为[201207],[20128]为[201208] 从…起 选择工资单,Forname,姓氏,年+月为d,金额从数据透视1开始
在[20113]、[20126]、[20127]、[20128]中,PivotSummup.Amount作为pvt出现在[20113]、[20126]、[20127]、[20128]中,有一个问题-是否有一种方法可以在动态列中使用ISNULL返回0?@HeavenCore嗯,这并不像看起来那么简单。我没有测试它,但我更新了我的答案,试图满足您的要求。如果需要,请告诉我works@bluefeet是的,我真的很偏执,当我写我的答案时,我会收到新的答案通知。你修改后的ISNULL代码效果很好-干杯,有一天我会掌握PIVOT的窍门:有几个问题,OP要求一个解决方案的动态版本。另外,您正在将年/月连接在一起,如果值为int,则将不起作用。int可以转换为nvarchar
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)