Ssas

ParallelPeriod 在日期維度中為 2 月 29 日返回 null

  • August 18, 2015

我有一個由物理日期表支持的日曆日期維度(最初是在 SQL Server 2000 上創建的,因此是日期時間而不是日期):

CREATE TABLE [dbo].[PostDate_Dimension](
   [post_date] [datetime] NOT NULL PRIMARY KEY,
   [day_of_year] [int] NOT NULL,
   [day_of_month] [int] NOT NULL,
   [month_of_year] [int] NOT NULL,
   [post_year]  AS (datepart(year,[post_date])),
   [post_month]  AS (datepart(month,[post_date])),
   [post_day]  AS (datepart(day,[post_date]))
)

Post Date 維度有四個屬性(列出了成員鍵列,其中一些在 DSV 中計算):

  1. 日期(維度鍵)- post_date
  2. 月 - post_year, post_month
  3. 季度 - post_year,post_quarter =DatePart(quarter, "post_date"))
  4. 年份 - post_year

顯然,這沒什麼太花哨的。我還有一些計算度量,它們使用 ParallelPeriod 來計算上一年的 YTD 數據,以便快速並排比較,而無需使用者選擇特定的日期片段。只需選擇目前年份,它就會找到其中包含銷售額的最新日期,然後與上一年的相同範圍進行比較。

在上一年找到合適的日期通常歸結為:

ParallelPeriod(
   [Post Date].[Post Date].[Year],
   1,
   Tail(
       NonEmpty(
           Descendants(
               [Post Date].CurrentMember,
               ,
               Leaves
           ),
           Measures.[Total Price]
       ),
       1
   ).Item(0)
)

Tail 呼叫是它在目前選定的 Post Date 成員(通常是目前年份)下查找最新日期的地方。這很好用。但是,如果返回 2 月 29 日,這意味著特定維度成員組合的最後一次銷售發生在 2 月 29 日,那麼它將 2 月 29 日傳遞給 ParallelPeriod 函式,該函式隨後返回 null。然後上一年的 YTD 度量也返回 null。

所以,簡而言之:基於這個特定的模式,有沒有一種簡單的方法可以讓 ParallelPeriod 在 2 月 29 日的輸入中表現良好?如果它只是返回上一年的 2 月 28 日,那很好。

編輯

我嘗試過的幾件事:

  • 使用這個表達式來調整 Post Date 成員:

Iif(MONTH([Post Date].[Post Date].CurrentMember.Member_Caption) = 2 And DAY([Post Date].[Post Date].CurrentMember.Member_Caption) = 29, [Post Date].[Post Date].CurrentMember.PREVMEMBER, [Post Date].[Post Date].CurrentMember)

這行得通,但程式碼會很糟糕,因為我必須[Post Date].[Post Date].CurrentMemberTail(NonEmpty(Descendants([Post Date].CurrentMember,, Leaves), Measures.[Total Price]), 1).Item(0)).

  • 使用 except 從結果中刪除所有 2 月 29 日的日期NonEmpty(Descendants([Post Date].CurrentMember,, Leaves), Measures.[Total Price])。我無法找出正確的語法(如果有的話)來從維度中獲取所有 2 月 29 日的集合。
  • 使用使用者定義函式創建一個 .NET 程序集,該函式將成員作為參數,如果是 2 月 29 日則返回前一個成員。似乎 Microsoft.AnalysisServices.AdomdServer 中的類非常有限,甚至沒有允許這個基本任務(甚至不檢索成員鍵作為日期值)。

另一種選擇是使用聯合來獲取目前和前一個成員的並行時間段。然後從中提取第一項,它將始終是目前成員(除了 2 月 29 日的情況,它應該回退到前一個成員)。

也就是說,與前一個成員並行週期有效合併,如下所示:

union 
(
   PARALLELPERIOD(
       [Date].[Fiscal Detail].[Fiscal Year],1,
       [Date].[Fiscal Detail].currentmember) 
   *(will be null if Feb 29)*
   ,
   PARALLELPERIOD(
       [Date].[Fiscal Detail].[Fiscal Year],1,
       [Date].[Fiscal Detail].currentmember.lag(1))  
   *(will be the prior year Feb 28 when above is Feb 29 )*    
).item(0)  *(get the first member out of the union set)*

引用自:https://dba.stackexchange.com/questions/14266