如何在MDX中透视SSAS多维数据集维度与属性关联结果?
MDX实现Cube维度属性的透视展示
我懂你想要的效果——把从$system.MDSchema_levels拿到的Cube、维度、属性关联列表,转成以维度+属性为行、各个Cube为列,用X标记是否包含的透视表。MDX确实没有SQL那样直接的PIVOT函数,但咱们可以通过计算成员和系统视图的组合来实现,下面是具体方案:
静态Cube列表的实现(适合Cube数量固定的场景)
如果你的5个Cube名称是已知的(比如CubeA、CubeB、CubeC、CubeD、CubeE),可以用下面的MDX脚本直接生成透视表:
WITH -- 为每个Cube定义计算成员,判断当前维度属性是否属于该Cube MEMBER [Measures].[CubeA] AS IIF(EXISTS( {([DIMENSION_UNIQUE_NAME].CurrentMember, [LEVEL_CAPTION].CurrentMember)}, [CUBE_NAME].[CubeA] ), 'X', '') MEMBER [Measures].[CubeB] AS IIF(EXISTS( {([DIMENSION_UNIQUE_NAME].CurrentMember, [LEVEL_CAPTION].CurrentMember)}, [CUBE_NAME].[CubeB] ), 'X', '') MEMBER [Measures].[CubeC] AS IIF(EXISTS( {([DIMENSION_UNIQUE_NAME].CurrentMember, [LEVEL_CAPTION].CurrentMember)}, [CUBE_NAME].[CubeC] ), 'X', '') MEMBER [Measures].[CubeD] AS IIF(EXISTS( {([DIMENSION_UNIQUE_NAME].CurrentMember, [LEVEL_CAPTION].CurrentMember)}, [CUBE_NAME].[CubeD] ), 'X', '') MEMBER [Measures].[CubeE] AS IIF(EXISTS( {([DIMENSION_UNIQUE_NAME].CurrentMember, [LEVEL_CAPTION].CurrentMember)}, [CUBE_NAME].[CubeE] ), 'X', '') SELECT -- 列:所有Cube的标记成员 {[Measures].[CubeA], [Measures].[CubeB], [Measures].[CubeC], [Measures].[CubeD], [Measures].[CubeE]} ON COLUMNS, -- 行:去重后的维度+属性组合 NON EMPTY [DIMENSION_UNIQUE_NAME].[DIMENSION_UNIQUE_NAME].MEMBERS * [LEVEL_CAPTION].[LEVEL_CAPTION].MEMBERS ON ROWS FROM ( -- 基础数据集:从系统视图筛选有效维度属性 SELECT [CUBE_NAME] AS [CUBE], [DIMENSION_UNIQUE_NAME] AS [DIMENSION], LEVEL_CAPTION AS [ATTRIBUTE] FROM $system.MDSchema_levels WHERE level_origin=2 AND LEVEL_NAME <> '(All)' )
代码说明:
- 计算成员:用
IIF+EXISTS组合,检查当前行的维度属性是否在对应Cube的结果集中,存在就返回X,否则留空。 - 行与列定义:把Cube标记成员放在列轴,维度和属性的交叉组合放在行轴,
NON EMPTY确保只保留至少被一个Cube使用的维度属性。 - 基础数据集:复用你原来的MDX查询,获取干净的维度属性关联数据。
动态Cube列表的实现(适合Cube数量不固定的场景)
如果Cube数量可能变化,MDX本身没法直接动态生成列,但可以分两步操作:
- 先获取所有Cube名称:运行下面的查询拿到当前实例下的所有Cube:
SELECT [CUBE_NAME] FROM $system.MDSchema_Cubes WHERE CUBE_TYPE = 'CUBE'
- 动态拼接MDX脚本:用PowerShell、SSIS或者其他脚本工具,把第一步得到的Cube名称自动拼接成WITH子句里的计算成员,再执行完整的透视查询。
注意事项:
- 确保
DIMENSION_UNIQUE_NAME返回的是维度的唯一标识(通常带方括号),避免名称冲突。 - 如果有重复的维度属性组合(比如同一个维度属性被多次返回),可以在基础数据集里加
DISTINCT过滤,或者依赖NON EMPTY自动去重。
内容的提问来源于stack exchange,提问作者DenStudent
相关产品推荐
相关产品推荐

