为何MDX Order函数ASC排序未按SSAS文档要求处理交叉连接层次?
版本
使用Microsoft Analysis Services 16.0.43.229版本。
问题
无法理解使用ASC排序的Crossjoin结合Order函数时的行为,其表现与文档描述不符。看起来它仅对最后一个层次进行排序,但文档说明仅在使用DESC时才会出现此情况:
指定ASC或DESC时,Order函数首先按成员在层次结构中的位置排列,然后对每个级别排序。
如果Order函数用于包含两个或多个层次结构的交叉连接集,且使用DESC标志,则仅对集中最后一个层次结构的成员排序。这与Analysis Services 2000中对所有层次结构排序的行为不同。
单层次ASC排序测试
以下MDX语句展示了对第一个层次的排序结果:
SELECT {[Measures].[Tax Amount]} ON 0, Order([Sales Territory].[Sales Territory].[Group].Members, [Measures].[Tax Amount], ASC) ON 1 FROM [Adventure Works]
| 区域 | 税额 |
|---|---|
| NA | (null) |
| Pacific | $852,426.90 |
| Europe | $1,584,046.16 |
| North America | $6,348,268.77 |
双层次交叉连接ASC排序测试
添加第二个层次进行Crossjoin时,预期第一个层次会保持上述排序(因为使用的是ASC而非DESC),但实际它按成员顺序排序:
SELECT {[Measures].[Tax Amount]} ON 0, Order([Sales Territory].[Sales Territory].[Group].Members * [Product].[Product Categories].[Category].Members, [Measures].[Tax Amount], ASC) ON 1 FROM [Adventure Works]
| 区域 | 类别 | 税额 |
|---|---|---|
| Europe | Accessories | $26,238.18 |
| Europe | Clothing | $32,110.44 |
| Europe | Components | $153,348.64 |
| Europe | Bikes | $1,372,348.90 |
| NA | Accessories | (null) |
| NA | Bikes | (null) |
| NA | Clothing | (null) |
| NA | Components | (null) |
| North America | Accessories | $62,515.40 |
| North America | Clothing | $128,244.56 |
| North America | Components | $774,285.38 |
| North America | Bikes | $5,383,223.44 |
| Pacific | Clothing | $9,054.06 |
| Pacific | Accessories | $13,011.05 |
| Pacific | Components | $16,292.11 |
| Pacific | Bikes | $814,069.68 |
预期结果
| 区域 | 类别 | 税额 |
|---|---|---|
| NA | Accessories | (null) |
| NA | Bikes | (null) |
| NA | Clothing | (null) |
| NA | Components | (null) |
| Pacific | Clothing | $9,054.06 |
| Pacific | Accessories | $13,011.05 |
| Pacific | Components | $16,292.11 |
| Pacific | Bikes | $814,069.68 |
| Europe | Accessories | $26,238.18 |
| Europe | Clothing | $32,110.44 |
| Europe | Components | $153,348.64 |
| Europe | Bikes | $1,372,348.90 |
| North America | Accessories | $62,515.40 |
| North America | Clothing | $128,244.56 |
| North America | Components | $774,285.38 |
| North America | Bikes | $5,383,223.44 |
解答
你遇到的问题源于对文档描述的误解,以及SSAS中Order函数对交叉连接集合的实际排序逻辑:
文档描述的歧义点:
文档中“指定ASC或DESC时,Order函数首先按成员在层次结构中的位置排列,然后对每个级别排序”的表述,这里的“每个级别”实际指的是交叉连接集合中的最后一个层次,而非所有层次。“按成员在层次结构中的位置排列”则是指交叉连接中前序层次会保留维度定义时的自然顺序,不会按指定度量排序。当前行为的原因:
当你对[Group].Members * [Category].Members使用Order(..., ASC)时,SSAS会先按照Group层次的自然成员顺序(Europe、NA、North America、Pacific)分组,然后仅对每个分组内的Category成员按Tax Amount升序排序,这就是你看到的结果。实现预期结果的方法:
若要先对Group层次按Tax Amount升序排序,再对每个Group下的Category成员排序,需要嵌套使用Order和Generate函数,让外层先排序Group,内层再排序每个Group下的Category:SELECT {[Measures].[Tax Amount]} ON 0, Generate( Order([Sales Territory].[Sales Territory].[Group].Members, [Measures].[Tax Amount], ASC), Order([Sales Territory].[Sales Territory].[Group].CurrentMember * [Product].[Product Categories].[Category].Members, [Measures].[Tax Amount], ASC) ) ON 1 FROM [Adventure Works]ASC与DESC的核心区别:
- 使用ASC时:前序层次保留自然顺序,仅最后一个层次按度量排序
- 使用DESC时:不保留任何层次的自然顺序,仅对最后一个层次按度量降序排序(所有前序层次的成员会被打乱,仅跟随最后一个层次的排序结果)
内容的提问来源于stack exchange,提问作者doc

