2017-05-09 62 views
0

我正在處理所有列需要根據列轉置爲行的報告。將所有列轉置爲基於不含PIVOT的列的行

CREATE TABLE TempTable(
    Company VARCHAR(5), 
    ProcessDate DATETIME, 
    OpExp DECIMAL, 
    Tax DECIMAL, 
    Total DECIMAL); 

INSERT INTO TempTable VALUES 
('Comp1', getdate(), 1000, 100, 1100), 
('Comp1', dateadd(year, -1, getdate()), 2000, 200, 2200), 
('Comp1', dateadd(year, -2, getdate()), 3000, 300, 3300); 

SELECT * FROM TempTable; 

enter image description here

但對報告中,我有這個錶轉成

enter image description here

這裏列2015年,2016年,2017年是動態的,這是基於 'Pr​​ocessDate' 一年。

我試着用PIVOT但它拋出

Incorrect syntax near 'PIVOT'. You may need to set the compatibility level of the current database to a higher value to enable this feature. See help for the SET COMPATIBILITY_LEVEL option of ALTER DATABASE 

由於數據庫已經在生產,所以不可能改變 兼容級別。

我與UNION ALL,CASE試圖在

Simple way to transpose columns and rows in Sql?

建議,但列數據類型是不同的,不能使用聚合函數的結果必須有所有行。

有沒有辦法將列轉換爲行?或者是否可以使用SSRS而不是RDLC生成此報告?

回答

0

這裏是SSRS唯一的辦法是可能做到這一點的最好辦法...

我在這個例子中擴展您的樣本數據一點點,包括9行,3行3家公司。

創建一個新的空白報告並正常添加您的數據集。 然後在報告上插入一個矩陣控件。 按下圖所示拖動字段以初始設置矩陣。我們將編輯這個,但它給了我們一個快速的開始。

注:第3步應閱讀「將ProcessDate這裏......」 enter image description here

現在,我們需要從過程日期chnage只是當年所以從第三步:右鍵單擊ProcessDate單元格,然後單擊「表達'。表達式設置爲

=YEAR(Fields!ProcessDate.Value)

下的組設計窗格中的報表設計,在[ProcessDate]列組單擊鼠標右鍵,選擇「組屬性」,設置組屬性設置爲相同的表達=YEAR(Fields!ProcessDate.Value)enter image description here

現在又回到了報表設計,(從上面的步驟4)用鼠標右鍵單擊該數據單元並做「插入行」 - >「內部組 - 低於」 enter image description here

重複此過程,添加第三排。

在兩個新的空白單元格中,單擊字段列表下拉菜單並分別選擇「稅」和「總計」。

enter image description here

如果你想添加一個標題欄。右鍵單擊其中的[Company]單元格,執行'Insert Column' - >'Inside Group - Right',然後右鍵單擊新單元格並選擇'拆分單元格',這將取消合併3行。然後你可以爲每一行輸入一個標題。 設計應該看起來像這樣。

enter image description here

這就是它真的..

最終輸出看起來是這樣的。

enter image description here

0

注意:您可以更改兼容級別。只要您將兼容級別更改爲更高的值,並且沒有依賴此數據庫的鏈接服務器等等,就不會影響任何內容。很明顯,如果你不確定,不要碰它

無論如何,有幾種方法可以做到這一點。這種方法使用UNION,我不知道你爲什麼說你不能使用這種方法,但是這給出了你的樣本期望值。

DECLARE @Temptable TABLE (
    Company VARCHAR(5), 
    ProcessDate DATETIME, 
    OpExp DECIMAL, 
    Tax DECIMAL, 
    Total DECIMAL); 

INSERT INTO @TempTable VALUES 
('Comp1', getdate(), 1000, 100, 1100), 
('Comp1', dateadd(year, -1, getdate()), 2000, 200, 2200), 
('Comp1', dateadd(year, -2, getdate()), 3000, 300, 3300); 

SELECT * FROM @TempTable 

DECLARE @ReportStartYear int = 2017 

SELECT 
    t.Company 
    , 'OpExp' as Val 
    , SUM(CASE YEAR(t.ProcessDate) WHEN @ReportStartYear -2 THEN OpExp ELSE 0 END) AS ColA 
    , SUM(CASE YEAR(t.ProcessDate) WHEN @ReportStartYear -1 THEN OpExp ELSE 0 END) AS ColB 
    , SUM(CASE YEAR(t.ProcessDate) WHEN @ReportStartYear THEN OpExp ELSE 0 END) AS ColC 
    , @ReportStartYear - 2 as ColACaption 
    , @ReportStartYear - 1 as ColBCaption 
    , @ReportStartYear as ColCCaption 
    FROM @Temptable t 
    GROUP BY t.Company 
UNION ALL 
SELECT 
    t.Company 
    , 'Tax' as Val 
    , SUM(CASE YEAR(t.ProcessDate) WHEN @ReportStartYear -2 THEN Tax ELSE 0 END) AS ColA 
    , SUM(CASE YEAR(t.ProcessDate) WHEN @ReportStartYear -1 THEN Tax ELSE 0 END) AS ColB 
    , SUM(CASE YEAR(t.ProcessDate) WHEN @ReportStartYear THEN Tax ELSE 0 END) AS ColC 
    , @ReportStartYear - 2 as ColACaption 
    , @ReportStartYear - 1 as ColBCaption 
    , @ReportStartYear as ColCCaption 
    FROM @Temptable t 
    GROUP BY t.Company 
UNION ALL 
SELECT 
    t.Company 
    , 'Total' as Val 
    , SUM(CASE YEAR(t.ProcessDate) WHEN @ReportStartYear -2 THEN Total ELSE 0 END) AS ColA 
    , SUM(CASE YEAR(t.ProcessDate) WHEN @ReportStartYear -1 THEN Total ELSE 0 END) AS ColB 
    , SUM(CASE YEAR(t.ProcessDate) WHEN @ReportStartYear THEN Total ELSE 0 END) AS ColC 
    , @ReportStartYear - 2 as ColACaption 
    , @ReportStartYear - 1 as ColBCaption 
    , @ReportStartYear as ColCCaption 
    FROM @Temptable t 
    GROUP BY t.Company 

這將返回以下

Company Val  ColA ColB ColC ColACaption ColBCaption ColCCaption 
Comp1 OpExp 3000 2000 1000 2015  2016  2017 
Comp1 Tax  300  200  100  2015  2016  2017 
Comp1 Total 3300 2200 1100 2015  2016  2017 

在報表中,您可以設置列標題是=FIRST(Fields!ColACaption.Value)等,所以你不必擔心列名是動態的。 如果您知道您將返回多少列,則此方法有效。

但是如果在SSRS中做到這一點可能更容易。創建一個矩陣,將列組設置爲一個返回ProcessDate列YEAR的表達式,然後在每個值類型的詳細組中添加一行(OpExp,Tax & Total),並且應該給你想要的東西也無需更改任何SQL。

+0

感謝您的建議。這是第一次在SSRS和谷歌工作,找到一個很好的鏈接,將列轉置爲使用表的SSRS中的行。 https://jl45sql.wordpress.com/2012/06/13/transposing-a-dataset-in-ssrs/ –

+0

帶有3行的Tablix會比這更簡單。我將使用您的示例數據做一個快速示例。 –