2012-10-25 151 views
3

看看下面的示例數據:的SQL Server 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 
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 

我將如何PIVOT這對年+月(如: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 

回答

4

好了,就像你說的,你會需要動態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 ('[email protected]+')) PT' 

EXEC(@Query) 
+0

現貨,歡呼 – HeavenCore

+0

一個問題 - 有沒有在動態列中使用ISNULL來返回0的方法? – HeavenCore

+0

@HeavenCore好吧,那看起來並不那麼容易。我沒有對它進行測試,但我更新了我的答案,嘗試實現您的要求。讓我知道它是否有效 – Lamak

-1

enter image description here選擇工資,的forName,姓,[20113]爲[201103],[20126]爲[201206] ,[20127]爲[201207],[20128]爲[201208] ,從 (選擇工資單,姓,名,年+月,d,金額來自pivot1)向上 pivot(up(up.Amount) d [20113],[20126],[20127],[20128]))爲pvt

+0

它是否太不禮貌? – Larry

+0

有幾個問題,OP請求解決方案的動態版本。另外,您將年/月連接在一起,如果值爲int,則不會工作。 – Taryn

+0

int可以被轉換成nvarchar – Larry