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]}
结果:
这里有两个简单的查询,显示按日期过滤的月份级别的数据。
在第一个查询中,我使用 "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]}
结果: