2013-02-22 78 views
2

我有一個表設置象下面這樣:SQL動態樞軸和組導致

CLIENTNAME   MONTHANDYEAR  RESOURCE  COST 
abc     JAN2011   res1   1000 
abc     FEB2011   res1   2000 
def     JAN2011   res2   1500 
def     MAR2011   res1   2000 
ghi     MAR2011   res3   2500

我需要的輸出像的下方。幾個月將在3個月的時間間隔內動態生成。在這種情況下,有沒有辦法通過MONTHANDYEAR以及按客戶端名稱進行分組?

RESOURCE CLIENTNAME  JAN2011  FEB2011  MAR2011 
res1  abc   1000   1000 
res1  def          2000 
res2  def   1500 
res3  ghi          2500 
+0

這裏面有多少已經* *在該數據庫上完成結束?例如,您可以在客戶端應用程序中構建您的查詢嗎?或者您是否使用可以進行數據透視/分組的報告解決方案? – 2013-02-22 04:20:26

+0

我們的報告軟件具有非常有限的功能,不能像上述那樣轉置數據。 – 0onetwo 2013-02-22 04:22:21

回答

1

這是PIVOT運算符是什麼:

SELECT 
    Resource, ClientName, 
    [JAN2011], [FEB2011], [MAR2011] 
FROM 
    (
    SELECT 
    * 
    FROM tblname 
) AS SourceTable 
PIVOT 
    (
    SUM(COST) 
    FOR MONTHANDYEAR IN ([JAN2011], [FEB2011], [MAR2011]) 
) AS PivotTable; 

由於您的使用@startDate作爲基準月動態選擇月份,則可以使用以下動態查詢:

DECLARE @startDate datetime 
SET @startDate = '2011-01-01' 

DECLARE @sql varchar(MAX) 
SET @sql = 'SELECT 
     Resource, ClientName, [' + 
      REPLACE(SUBSTRING(CONVERT(varchar, @startDate, 13), 4, 8), ' ', '') + '], [' + 
      REPLACE(SUBSTRING(CONVERT(varchar, DATEADD(MONTH, 1, @startDate), 13), 4, 8), ' ', '') + '], [' + 
      REPLACE(SUBSTRING(CONVERT(varchar, DATEADD(MONTH, 2, @startDate), 13), 4, 8), ' ', '') + '] 
     FROM 
      (
      SELECT 
      * 
      FROM tblName 
     ) AS SourceTable 
     PIVOT 
      (
      SUM(COST) 
      FOR MONTHANDYEAR IN (' + 
        QUOTENAME(REPLACE(SUBSTRING(CONVERT(varchar, @startDate, 13), 4, 8), ' ', '')) + ', ' + 
        QUOTENAME(REPLACE(SUBSTRING(CONVERT(varchar, DATEADD(MONTH, 1, @startDate), 13), 4, 8), ' ', '')) + ', ' + 
        QUOTENAME(REPLACE(SUBSTRING(CONVERT(varchar, DATEADD(MONTH, 2, @startDate), 13), 4, 8), ' ', '')) + ') 
     ) AS PivotTable' 

execute(@sql) 

工作sqlfiddle here

+0

@ 0onetwo,根據您的規格進行動態查詢更新 – PinnyM 2013-02-22 14:45:12

+0

這真棒。感謝堆。 – 0onetwo 2013-02-25 00:37:15

0
SELECT Resource, Clientname 
, SUM(CASE WHEN MonthAndYear = 'JAN2011' THEN COST ELSE 0 END) AS JAN2011 
, SUM(CASE WHEN MonthAndYear = 'FEB2011' THEN COST ELSE 0 END) AS FEB2011 
, SUM(CASE WHEN MonthAndYear = 'MAR2011' THEN COST ELSE 0 END) AS MAR2011 
FROM yourtable 
GROUP BY Resource, Clientname 

您也可以刪除ELSE 0返回資源/ CLIENTNAME組合一個NULL值沒有數據

+0

非常感謝,但我應該補充說,這些月份需要動態生成,每次三個月。 – 0onetwo 2013-02-22 04:32:44

+0

@ 0onetwo,你可以通過這些月份名作爲參數,或單個參數逗號分隔的列表? – PinnyM 2013-02-22 04:36:01

+0

開始的月份將作爲參數傳入,查詢將執行該月和接下來兩個月的計算。 – 0onetwo 2013-02-22 04:48:20

1

這個數據轉換可以與PIVOT函數來完成。

如果你知道的值,那麼你可以硬編碼的monthandyear日期:

select resource, 
    clientname, 
    isnull(jan2011, '') Jan2011, 
    isnull(feb2011, '') Feb2011, 
    isnull(mar2011, '') Mar2011 
from 
(
    select clientname, monthandyear, resource, cost 
    from yourtable 
) src 
pivot 
(
    sum(cost) 
    for monthandyear in (Jan2011, Feb2011, Mar2011) 
) piv; 

SQL Fiddle with Demo

但是,如果日期是未知的,那麼你就需要使用動態SQL:

​​

SQL Fiddle with Demo

共同作用的結果是:

| RESOURCE | CLIENTNAME | JAN2011 | FEB2011 | MAR2011 | 
------------------------------------------------------- 
|  res1 |  abc | 1000 | 2000 |  0 | 
|  res1 |  def |  0 |  0 | 2000 | 
|  res2 |  def | 1500 |  0 |  0 | 
|  res3 |  ghi |  0 |  0 | 2500 | 
+0

非常感謝。我希望我可以給你勾選爲好,但PinnyM的回答爲我工作好一點。 – 0onetwo 2013-02-25 00:36:43

+0

@ 0onetwo投票贊同! :) – Taryn 2013-02-25 00:38:28