今天在天善問答里看到一個問題,如果我沒有理解錯的話,它應該是指比如在一個報表中選取一個時間段,然后求出這個時間段的某個 Measure 的 SUM 和。並且同時求出這兩個時間點對應的上一年的時間點之間的同一個 Measure 的 SUM 和。
比如當前選取的時間點是 2004年1月8日,結束時間點是 2004年3月1日。那么不僅要求這個時間段的某度量值總和,並且還要求 2003年1月8日到2003年3月1日時間段的某度量值總和。 也就是說,這個時間段是一個動態的,根據輸入的兩個時間段決定當年和上一年的計算。
這個里面有幾個小知識點,於是總結了一下,先看下面這個 Report 的效果。
還有使用 Date Picker 的效果 (注意如果使用日歷控件,那么 StartDate 和 EndDate 的類型都是 Date/Time 類型)-
非 Date Picker 參數時的設計
在 Cube 中查一下驗證一下,查詢結果都是一樣的。
WITH MEMBER [Measures].[Reseller Sales Amount of Period]
AS
SUM( [Date].[Calendar].[Date].&[20040108]:[Date].[Calendar].[Date].&[20040301] ,[Measures].[Reseller Sales Amount] ) MEMBER [Measures].[Reseller Sales Amount of Last Period]
AS
SUM( [Date].[Calendar].[Date].&[20030108]:[Date].[Calendar].[Date].&[20030301] ,[Measures].[Reseller Sales Amount] ) SELECT NON EMPTY{[Measures].[Reseller Sales Amount of Period], [Measures].[Reseller Sales Amount of Last Period]} ON COLUMNS, NON EMPTY { ([Product].[Category].[Category].ALLMEMBERS ) } ON ROWS FROM [Step-by-Step]
新建一個 Dataset - Datedata,連接的是 MDX Step by Step 中的示例Cube。
MDX 查詢語句取得時間成員和可以用在 Report 下拉框中的標簽。
WITH MEMBER [Measures].[DateValue]
AS
[Date].[Calendar].CurrentMember.UniqueName MEMBER [Measures].[DateLabel]
AS
[Date].[Calendar].CurrentMember.Name SELECT { [Measures].[DateValue], [Measures].[DateLabel] } ON COLUMNS, { [Date].[Calendar].[Date]} ON ROWS FROM [Step-by-Step]
創建兩個時間參數 StartDate 和 EndDate 並且綁定到 DateData 中的時間成員,它們選擇的都是 Text 類型,這一點一定要注意!!!。
新建一個 Dataset 用來展現表格上的數據,注意在 SSRS Report 中的參數使用一般都是通過這種類似於子查詢的方式完成的。
WITH MEMBER [Measures].[Reseller Sales Amount of Last Year]
AS SUM( { -- 根據傳入的參數分別取得上一年的開始時間點和結束時間點
PARALLELPERIOD([Date].[Calendar].[Calendar Year], 1, STRTOMEMBER(@FromDateCalendar, CONSTRAINED) ): PARALLELPERIOD([Date].[Calendar].[Calendar Year], 1, STRTOMEMBER(@ToDateCalendar, CONSTRAINED) ) }, [Measures].[Reseller Sales Amount] ) SELECT NON EMPTY {[Measures].[Reseller Sales Amount], [Measures].[Reseller Sales Amount of Last Year]} ON COLUMNS, NON EMPTY { ([Product].[Category].[Category].ALLMEMBERS ) } ON ROWS FROM ( -- Report 傳入的開始參數和結束參數
SELECT ( STRTOMEMBER(@FromDateCalendar, CONSTRAINED) : STRTOMEMBER(@ToDateCalendar, CONSTRAINED) ) ON COLUMNS FROM [Step-by-Step] )
保存並在 Dataset 中綁定兩個時間參數。
這樣基本上就完成了基於時間區間的同比時間段的報表。
還有一點要注意一下,比如像這個查詢是不會返回結果的,因為2004年的上一年不是閏年。
但是是有2003年2月28日這一天的,盡管下面的查詢返回一個 NULL 但是這個成員是存在的。
Date Picker 時的設計
在文章一開始的時候就介紹了,如果把時間參數設計成日歷形式那么就需要將參數的類型從 Text 類型改成 Date/Time 類型。
並且這里沒有指定可供選擇的值,因為一旦指定了值日歷控件的樣式就又會變成下拉框的樣式。
同時在 DateSet 那里要改變參數的格式,因為 Date\Time 類型是時間類型,並不是字符串類型,因此需要將它們轉變成字符串格式。
轉變的格式代碼如下:
="[Date].[Calendar].[Date].&["& Format(CDate(Parameters!StartDate.Value),"yyyyMMdd") + "]"
你可以從網上搜索到很多種不同的別人告訴你如何轉換格式的經驗和代碼,但是要注意,你首先要確定的是你要轉換的對象是什么?它需要什么格式?
先最好能夠通過下面這種最簡單的代碼查看一下這種 Hard Code 形式的參數行不行,沒有問題之后再放到上面去編輯。
在網上搜索到的轉換過程一般都是使用作者自己代碼示例的層次結構,比如說有的就是[Date].[Calendar].&[20040228], 少了一個 Level。
第二就是轉換的字符串格式可能並不是 yyyyMMdd 的類型,而是 yyyy-MM-dd 的類型,所以這兩點一定要注意。注意到了,你的轉換才會成功!
最后一個問題,就是如果用戶選擇了一個非法的成員傳入的時候就會出現這個錯誤,原因是我們的成員並不包含 11/1/2013 或者 11/29/2013。所以實際上還是使用下拉框的形式最直接,最簡單,因為它可直接限定可選擇的內容,可以做成年月日級聯的效果。
總結:
- 在 SSRS Report 中使用下拉框等具有值和標簽特征的組件時,可以參照本文的方式來綁定。
- 有關 SSRS Report 傳遞 MDX 查詢參數的相關文章還可以參看 SSRS 系列 - 使用帶參數的 MDX 查詢實現一個分組聚合功能的報表。
- 有關 MDX 時間函數 PARALLELPERIOD 可以參看這篇文章 MDX Step by Step 讀書筆記(九) - Working with Time 處理時間。
- STRTOMEMBER 函數的使用也需要注意一下,還有其它比較類似的例如 STRTOSET 等等都是可以將字符串轉成對象或者集合。
更多 BI 文章請參看 BI 系列隨筆列表 (SSIS, SSRS, SSAS, MDX, SQL Server)
如果覺得這篇文章看了對您有幫助,請幫助推薦,以方便他人在 BIWORK 博客推薦欄中快速看到這些文章。