AdventureWorks 日期维度根据所选层次结构显示不同的结果

AdventureWorks date dimension shows different results depending on selected hierarchy

这里有两个简单的查询,显示按日期过滤的月份级别的数据。

在第一个查询中,我使用 "Date.Calendar" 用户层次结构的月份级别。

SELECT 
    NON EMPTY { [Measures].[Internet Sales Amount] } ON 0,
    NON EMPTY { [Date].[Calendar].[Month].&[2013]&[1] } ON 1
FROM    [Adventure Works]
WHERE   {[Date].[Date].&[20130105]:[Date].[Date].&[20130106]}

并收到 - 2013 年 1 月 -> 857,689.91 美元 Results

在第二个查询中,我使用 "Date.Month of Year" 属性层次结构。

SELECT 
    NON EMPTY { [Measures].[Internet Sales Amount]} ON 0,
    NON EMPTY { [Date].[Month of Year].&[1] } ON 1
FROM    [Adventure Works]
WHERE   { [Date].[Date].&[20130105] : [Date].[Date].&[20130106] }

并收到 - 一月 -> $54,468.46 Results

我不明白为什么这两个查询显示不同的结果。如果使用相同的维度并且数据是 filtered/sliced 尽可能最好的水平。

以下是每个日期的值。

SELECT 
    NON EMPTY { [Measures].[Internet Sales Amount]} ON 0,
    NON EMPTY { [Date].[Calendar].[Date] } ON 1
FROM    [Adventure Works]
WHERE   { [Date].[Date].&[20130105] : [Date].[Date].&[20130106] }

2013 年 1 月 5 日 32,681.44 美元

2013 年 1 月 6 日 $21,787.02

Result

这两个日期的总价值等于第二个查询的结果 - $54,468.46

我知道第一个查询是用户层次结构,第二个查询是日期维度的属性层次结构,但我无法弄清楚哪个规则告诉我们以不同方式计算这些值。

如果有人能解释背后的逻辑-那将非常有帮助。任何 link 解释此逻辑的某些资源也可能有所帮助。

顺便说一句:我已经创建了具有简单日期维度的简单多维数据集,它仅由属性层次结构(日期、月份、年份)组成,它仍然像在第一个查询中一样工作,所以不清楚为什么它会这样。

我探索了这种行为的原因,我想我已经找到了原因。下面的解释是基于书 SQL SERVER 2008 MDX Step by Step pages 51-58 (especially Avoiding Reference Conflicts)。

您的问题是典型的引用冲突 problem.In MDX 层次结构不能在给定的元组中多次使用,但是如果您使用的是用户层次结构及其底层属性层次结构,您基本上是 -通过这个检查。这就是您查询中发生的情况

在您的第一个查询中,您使用的是用户层次结构

[Date].[Calendar].[Month].&[2013]&1

在 MDX 中,用户层次结构被转换为属性层次结构。在您的第一个查询中

SELECT NON EMPTY { [Measures].[Internet Sales Amount] } ON 0, NON EMPTY { [Date].[Calendar].[Month].&[2013]&1 } ON 1 FROM [Adventure Works] WHERE
{[Date].[Date].&[20130105]:[Date].[Date].&[20130106]}

您正在使用用户层次结构“[Date].[Calendar].[Month].&[2013]&1”,其最后一级具有“[Date].[Date] ”。然后在 where 子句中使用相同的“[Date].[Date]”属性层次结构进行过滤。由于在 USER 层次结构中您没有使用叶级别,因此您创建了一个部分地址,因此成员及其祖先被解析。翻译中忽略所有后代。看看下面的查询(这是基于你的第一个查询,我特意删除了你的 where 子句)。

with member [Measures].[CalendarYear] as [Date].[Calendar Year].currentmember.name
member [Measures].[CalendarSemester] as  [Date].[Calendar Semester of Year].currentmember.name
member [Measures].[CalendarQuater] as  [Date].[Calendar Quarter of Year].currentmember.name
member [Measures].[CalendarMonth] as  [Date].[Month of Year].currentmember.name
member [Measures].[CalendarDate] as [Date].[Date].currentmember.name
SELECT 
NON EMPTY { [Measures].[Internet Sales Amount] ,[Measures].[CalendarYear],[Measures].[CalendarSemester],[Measures].[CalendarQuater],[Measures].[CalendarMonth],[Measures].[CalendarDate]} ON 0,
NON EMPTY { [Date].[Calendar].[Month].&[2013]&[1] } ON 1
FROM    [Adventure Works] 

结果。

请注意日历年、学期和季度都显示非默认值。但我们从未使用过它们。这表明用户层次结构已转换为基础属性层次结构。现在看看日历,它仍然显示 "All Period"。既然被忽略了。 现在,如果您将 where 子句添加回来,日期仍然显示 "All Period",原因有两个 1)因为在User Hierarchy翻译中被忽略了, 2)你在哪里使用了一个范围。如果将行轴元组替换为 where 元组,它仍将显示 "All Period" 作为范围的基础。然而,解决它只需要两个日期。

基于此,在解析您的查询时,它对 Date 属性层次结构有两种翻译,一种表示根据用户层次结构忽略它,另一种提供了一个范围。这是由于冲突导致结果不正确的地方。

现在让我们考虑一下您之前在评论中提出的问题

with member [Measures].[CalendarYear] as [Date].[Calendar Year].currentmember.name
member [Measures].[CalendarSemester] as  [Date].[Calendar Semester of Year].currentmember.name
member [Measures].[CalendarQuater] as  [Date].[Calendar Quarter of Year].currentmember.name
member [Measures].[CalendarMonth] as  [Date].[Month of Year].currentmember.name
member [Measures].[CalendarDate] as [Date].[Date].currentmember.name
SELECT 
NON EMPTY { [Measures].[Internet Sales Amount] ,[Measures].[CalendarYear],[Measures].[CalendarSemester],[Measures].[CalendarQuater],[Measures].[CalendarMonth],[Measures].[CalendarDate]} ON 0,
NON EMPTY { [Date].[Calendar].[Month].&[2013]&[1] } ON 1
FROM    [Adventure Works]
WHERE   {[Date].[Date].&[20130105]}

结果:

请注意,这次使用的是单个成员的解析,而不是用户层次解析。现在这种行为可能是由于一个翻译给出 "All Period" 而下一个翻译给出一个成员,因此该成员获胜。

为了进一步证实这一点,我对我的 AdventureWorks 示例进行了更改。 Date 属性层次结构基于 "Simple Date" 列。我将 "Simple Date" 作为一个单独的属性公开并处理了我的多维数据集。

查看 "Simple Date" 查询和结果。

with member [Measures].[CalendarYear] as [Date].[Calendar Year].currentmember.name
member [Measures].[CalendarSemester] as  [Date].[Calendar Semester of Year].currentmember.name
member [Measures].[CalendarQuater] as  [Date].[Calendar Quarter of Year].currentmember.name
member [Measures].[CalendarMonth] as  [Date].[Month of Year].currentmember.name
member [Measures].[CalendarDate] as [Date].[Date].currentmember.name
SELECT 
NON EMPTY { [Measures].[Internet Sales Amount] ,[Measures].[CalendarYear],[Measures].[CalendarSemester],[Measures].[CalendarQuater],[Measures].[CalendarMonth],[Measures].[CalendarDate]} ON 0,
NON EMPTY { [Date].[Calendar].[Month].&[2013]&[1] } ON 1
FROM    [Adventure Works]
WHERE   
--{[Date].[Date].&[20130105]}
{[Date].[Simple Date].&[20130105]:[Date].[Simple Date].&[20130106]}

结果: