Top X of Top Y with RestOf 成员,其中 X 和 Y 是来自不同维度的层次结构
Top X of Top Y with RestOf member where X and Y are hierarchies from different dimensions
这很好用:
WITH
SET [AllCountries] AS [Country].[Country].MEMBERS
SET [AllStates] AS [State-Province].[State-Province].MEMBERS
SET [Top2States] AS
Generate
(
[AllCountries]
,TopCount
(
(EXISTING
[AllStates])
,3
,[Measures].[Internet Order Count]
)
)
MEMBER [State-Province].[All].[RestOfCountry] AS
Aggregate({(EXISTING {[AllStates]} - [Top2States])})
SELECT
{[Measures].[Internet Order Count]} ON COLUMNS
,{
[AllCountries]
*
{
[State-Province].[All]
,[Top2States]
,[State-Province].[All].[RestOfCountry]
}
} ON ROWS
FROM [Adventure Works];
EXISTING
关键字很有帮助。
如果两个层级 ON ROWS
不是来自同一个维度,就像国家和州在上面的方式,那么我们有类似下面的东西:
WITH
SET [AllCountries] AS [Country].[Country].MEMBERS
SET [AllCats] AS [Product].[Category].[Category].MEMBERS
SET [Top5Cats] AS
Generate
(
[AllCountries]
,TopCount
(
(EXISTING
[AllCats])
,5
,[Measures].[Internet Order Count]
)
)
MEMBER [Product].[Category].[All].[RestOfProds] AS
Aggregate({(EXISTING {[AllCats]} - [Top5Cats])})
SELECT
{[Measures].[Internet Order Count]} ON COLUMNS
,{
[AllCountries]
*
{
[Product].[Category].[All]
,[Top5Cats]
,[Product].[Category].[All].[RestOfCountry]
}
} ON ROWS
FROM [Adventure Works];
您可以在上面的结果中看到,同一组类别以相同的顺序针对每个国家/地区重复,即引擎没有找到每个国家/地区的 topCount。 EXISTING
现在是多余的。
我们如何调整上面的第二个脚本,使其具有与顶部脚本相似的功能?
编辑
一个更好的例子是下面使用 Product.就好像引擎正在为所有国家/地区找到 TopCount
,然后针对每个国家/地区放置相同的集合。我想要每个国家的 TopCount
:
WITH
SET [AllCountries] AS
[Country].[Country].MEMBERS
SET [AllProds] AS
[Product].[Product].[Product].MEMBERS
SET [Top5Prods] AS
Generate
(
[AllCountries]
,TopCount
(
(EXISTING
[AllProds])
,5
,[Measures].[Internet Order Count]
)
)
MEMBER [Product].[Product].[All].[RestOfProds] AS
Aggregate({(EXISTING {[AllProds]} - [Top5Prods])})
SELECT
{[Measures].[Internet Order Count]} ON COLUMNS
,NON EMPTY
{
[AllCountries]
*
{
[Product].[Product].[All]
,[Top5Prods]
,[Product].[Product].[All].[RestOfProds]
}
} ON ROWS
FROM [Adventure Works];
编辑2
这是根据 Sourav 的想法得出的最新版本 - 不幸的是,RestOfProds 成员无法正常运行:
WITH
SET [AllCountries] AS
[Country].[Country].MEMBERS
SET [AllProds] AS
[Product].[Product].[Product].MEMBERS
SET [Top5Prods] AS
Generate
(
[AllCountries] AS a
,
{
(
a.Current
,[Product].[Product].[All]
)
+
//The top x prods
TopCount
(
NonEmpty
(
a.Current * [AllProds]
,[Measures].[Internet Sales Amount]
)
,5
,[Measures].[Internet Sales Amount]
)
}
)
SET [RestOfProds] AS
Extract
(
{[AllCountries] * [AllProds]} - [Top5Prods]
,[Product].[Product]
)
MEMBER [Product].[Product].[All].[RestOfProds] AS
Aggregate([RestOfProds])
SELECT
{[Measures].[Internet Sales Amount]} ON COLUMNS
,{
[Top5Prods]
,
[AllCountries] * [Product].[Product].[All].[RestOfProds]
} ON ROWS
FROM [Adventure Works];
编辑3
以下顺序正确,因此成员 RestOfProds
始终遵循其各自的前 5
WITH
SET [AllCountries] AS
[Country].[Country].MEMBERS
SET [AllProds] AS
[Product].[Product].[Product].MEMBERS
SET [Top5Prods] AS
Generate
(
[AllCountries] AS a
,{
//The top x prods
TopCount
(
NonEmpty
(
a.Current * [AllProds]
,[Measures].[Internet Sales Amount]
)
,5
,[Measures].[Internet Sales Amount]
)
}
)
MEMBER [Product].[Product].[All].[RestOfProds] AS
Aggregate([Country].CurrentMember * [AllProds] - [Top5Prods])
SELECT
{[Measures].[Internet Sales Amount]} ON COLUMNS
,Generate
(
[AllCountries] AS X
,
Order
(
Intersect
(
X.CurrentMember * [AllProds]
,[Top5Prods]
)
,[Measures].[Internet Sales Amount]
,bdesc
)
+
{X.CurrentMember * {[Product].[Product].[All].[RestOfProds]}}
) ON ROWS
FROM [Adventure Works];
编辑4
以下顺序正确,因此成员 RestOfProds
始终位于其各自的前 5 位 + 我在行中添加了进一步的集合:
WITH
SET [2months] AS
{
[Date].[Calendar].[Month].&[2007]&[9]
,[Date].[Calendar].[Month].&[2007]&[10]
}
SET [AllCountries] AS
[Country].[Country].MEMBERS
SET [MthsCountries] AS
[2months] * [AllCountries]
SET [AllProds] AS
[Product].[Product].[Product].MEMBERS
SET [Top5Prods] AS
Generate
(
[MthsCountries] AS A
,{
//The top x prods
TopCount
(
NonEmpty
(
A.Current * [AllProds]
,[Measures].[Internet Sales Amount]
)
,5
,[Measures].[Internet Sales Amount]
)
}
)
MEMBER [Product].[Product].[All].[RestOfProds] AS
Aggregate
(
([Date].[Calendar].CurrentMember,[Country].CurrentMember) * [AllProds]
-
[Top5Prods]
)
SELECT
{[Measures].[Internet Sales Amount]} ON COLUMNS
,Generate
(
[MthsCountries] AS X
,
Order
(
Intersect
(
X.Current * [AllProds]
,[Top5Prods]
)
,[Measures].[Internet Sales Amount]
,bdesc
)
+
{X.Current * {[Product].[Product].[All].[RestOfProds]}}
) ON ROWS
FROM [Adventure Works];
如果您在同一维度中交叉连接多个层次结构,则只会显示有效组合。这称为自动存在,它解释了为什么第一个查询按您想要的方式工作。
当交叉连接来自不同维度的层次结构时,自动存在不会发生。我认为这解释了第二个查询中 returned 的奇怪组合。
尝试在 ON ROWS 定义的开头添加 NON EMPTY。然后它只会 return 具有 Internet Order Count 度量值的组合(无论列上的度量)。这是限制交叉连接的正确方法。
如果您不想在 Internet 订单计数上使用 NON EMPTY,那么您需要在不同的度量上使用 NonEmpty(, [Measures].[A Different Measure])?
编辑:看起来这个问题与自动存在无关,而是与每个国家/地区执行不同的 TopCount 有关。所以这个信息可能会帮助其他人,但不是这个问题的答案。
EXISTING
在命名集上使用时,并没有真正的区别,因为命名集是在布局轴成员之前创建的。在您的情况下, GENERATE
实际上只是创建静态集,然后在轴上的所有内容都只是交叉连接。
要使 TopCount
脚本正常工作,您需要处理一组中的所有 cross joins
,以便一起评估所有内容。我不确定,但您可以尝试以下操作:
WITH
SET [AllCountries] AS [Country].[Country].MEMBERS
SET [AllCats] AS [Product].[Category].[Category].MEMBERS
SET [Top5Cats] AS
Generate
(
[AllCountries] as a
,
{
(a.current , [Product].[Category].[All] ) //The ALL member
+
TopCount //The top 2 categories
(
NonEmpty((a.current * [AllCats] ) , (a.CURRENT, [Measures].[Internet Order Count]))
,2
,[Measures].[Internet Order Count]
)
}
+
{ //The rest of the members
a.current * [AllCats]
-
a.current *{
TopCount
(
NonEmpty([AllCats] , (a.CURRENT, [Measures].[Internet Order Count]))
,2
,[Measures].[Internet Order Count]
)
}
}
)
MEMBER [Product].[Category].[All].[RestOfProds] AS
Aggregate({(EXISTING {[AllCats]} - [Top5Cats])})
SELECT
{[Measures].[Internet Order Count]} ON COLUMNS,
[Top5Cats] ON ROWS
FROM [Adventure Works];
编辑:
如果你需要RestOfCats
成员,你可以添加这个代码。
SET [RestOfCats] AS
EXTRACT
(
{
[AllCountries] * [AllCats]
-
[Top5Cats]
},
[Product].[Category]
)
MEMBER [Product].[Category].[All].[RestOfCats] AS
Aggregate([RestOfCats])
编辑 2
继续您的示例,在定义中另外删除 'All' 成员。
SET [RestOfProds] AS
Extract
(
{[AllCountries] * [AllProds]} - [Top5Prods] - [AllCountries]*[Product].[Product].[All]
,[Product].[Product]
)
这似乎工作正常:
WITH
SET [AllCountries] AS
[Country].[Country].MEMBERS
SET [AllProds] AS
[Product].[Product].[Product].MEMBERS
SET [Top5Prods] AS
Generate
(
[AllCountries] AS a
,{
(
a.CurrentMember
,[Product].[Product].[All]
)
+
//The top x prods
a.CurrentMember
*
TopCount
(
[AllProds]
,5
,[Measures].[Internet Sales Amount]
)
}
)
MEMBER [Product].[Product].[All].[Other Products] AS
Aggregate
(
[Country].CurrentMember * [Product].[Product].[Product].MEMBERS
-
[Top5Prods]
)
SELECT
{[Measures].[Internet Sales Amount]} ON COLUMNS
,Hierarchize(
{
[Top5Prods]
,[AllCountries] * [Product].[Product].[All].[Other Products]
}
) ON ROWS
FROM [Adventure Works];
这很好用:
WITH
SET [AllCountries] AS [Country].[Country].MEMBERS
SET [AllStates] AS [State-Province].[State-Province].MEMBERS
SET [Top2States] AS
Generate
(
[AllCountries]
,TopCount
(
(EXISTING
[AllStates])
,3
,[Measures].[Internet Order Count]
)
)
MEMBER [State-Province].[All].[RestOfCountry] AS
Aggregate({(EXISTING {[AllStates]} - [Top2States])})
SELECT
{[Measures].[Internet Order Count]} ON COLUMNS
,{
[AllCountries]
*
{
[State-Province].[All]
,[Top2States]
,[State-Province].[All].[RestOfCountry]
}
} ON ROWS
FROM [Adventure Works];
EXISTING
关键字很有帮助。
如果两个层级 ON ROWS
不是来自同一个维度,就像国家和州在上面的方式,那么我们有类似下面的东西:
WITH
SET [AllCountries] AS [Country].[Country].MEMBERS
SET [AllCats] AS [Product].[Category].[Category].MEMBERS
SET [Top5Cats] AS
Generate
(
[AllCountries]
,TopCount
(
(EXISTING
[AllCats])
,5
,[Measures].[Internet Order Count]
)
)
MEMBER [Product].[Category].[All].[RestOfProds] AS
Aggregate({(EXISTING {[AllCats]} - [Top5Cats])})
SELECT
{[Measures].[Internet Order Count]} ON COLUMNS
,{
[AllCountries]
*
{
[Product].[Category].[All]
,[Top5Cats]
,[Product].[Category].[All].[RestOfCountry]
}
} ON ROWS
FROM [Adventure Works];
您可以在上面的结果中看到,同一组类别以相同的顺序针对每个国家/地区重复,即引擎没有找到每个国家/地区的 topCount。 EXISTING
现在是多余的。
我们如何调整上面的第二个脚本,使其具有与顶部脚本相似的功能?
编辑
一个更好的例子是下面使用 Product.就好像引擎正在为所有国家/地区找到 TopCount
,然后针对每个国家/地区放置相同的集合。我想要每个国家的 TopCount
:
WITH
SET [AllCountries] AS
[Country].[Country].MEMBERS
SET [AllProds] AS
[Product].[Product].[Product].MEMBERS
SET [Top5Prods] AS
Generate
(
[AllCountries]
,TopCount
(
(EXISTING
[AllProds])
,5
,[Measures].[Internet Order Count]
)
)
MEMBER [Product].[Product].[All].[RestOfProds] AS
Aggregate({(EXISTING {[AllProds]} - [Top5Prods])})
SELECT
{[Measures].[Internet Order Count]} ON COLUMNS
,NON EMPTY
{
[AllCountries]
*
{
[Product].[Product].[All]
,[Top5Prods]
,[Product].[Product].[All].[RestOfProds]
}
} ON ROWS
FROM [Adventure Works];
编辑2
这是根据 Sourav 的想法得出的最新版本 - 不幸的是,RestOfProds 成员无法正常运行:
WITH
SET [AllCountries] AS
[Country].[Country].MEMBERS
SET [AllProds] AS
[Product].[Product].[Product].MEMBERS
SET [Top5Prods] AS
Generate
(
[AllCountries] AS a
,
{
(
a.Current
,[Product].[Product].[All]
)
+
//The top x prods
TopCount
(
NonEmpty
(
a.Current * [AllProds]
,[Measures].[Internet Sales Amount]
)
,5
,[Measures].[Internet Sales Amount]
)
}
)
SET [RestOfProds] AS
Extract
(
{[AllCountries] * [AllProds]} - [Top5Prods]
,[Product].[Product]
)
MEMBER [Product].[Product].[All].[RestOfProds] AS
Aggregate([RestOfProds])
SELECT
{[Measures].[Internet Sales Amount]} ON COLUMNS
,{
[Top5Prods]
,
[AllCountries] * [Product].[Product].[All].[RestOfProds]
} ON ROWS
FROM [Adventure Works];
编辑3
以下顺序正确,因此成员 RestOfProds
始终遵循其各自的前 5
WITH
SET [AllCountries] AS
[Country].[Country].MEMBERS
SET [AllProds] AS
[Product].[Product].[Product].MEMBERS
SET [Top5Prods] AS
Generate
(
[AllCountries] AS a
,{
//The top x prods
TopCount
(
NonEmpty
(
a.Current * [AllProds]
,[Measures].[Internet Sales Amount]
)
,5
,[Measures].[Internet Sales Amount]
)
}
)
MEMBER [Product].[Product].[All].[RestOfProds] AS
Aggregate([Country].CurrentMember * [AllProds] - [Top5Prods])
SELECT
{[Measures].[Internet Sales Amount]} ON COLUMNS
,Generate
(
[AllCountries] AS X
,
Order
(
Intersect
(
X.CurrentMember * [AllProds]
,[Top5Prods]
)
,[Measures].[Internet Sales Amount]
,bdesc
)
+
{X.CurrentMember * {[Product].[Product].[All].[RestOfProds]}}
) ON ROWS
FROM [Adventure Works];
编辑4
以下顺序正确,因此成员 RestOfProds
始终位于其各自的前 5 位 + 我在行中添加了进一步的集合:
WITH
SET [2months] AS
{
[Date].[Calendar].[Month].&[2007]&[9]
,[Date].[Calendar].[Month].&[2007]&[10]
}
SET [AllCountries] AS
[Country].[Country].MEMBERS
SET [MthsCountries] AS
[2months] * [AllCountries]
SET [AllProds] AS
[Product].[Product].[Product].MEMBERS
SET [Top5Prods] AS
Generate
(
[MthsCountries] AS A
,{
//The top x prods
TopCount
(
NonEmpty
(
A.Current * [AllProds]
,[Measures].[Internet Sales Amount]
)
,5
,[Measures].[Internet Sales Amount]
)
}
)
MEMBER [Product].[Product].[All].[RestOfProds] AS
Aggregate
(
([Date].[Calendar].CurrentMember,[Country].CurrentMember) * [AllProds]
-
[Top5Prods]
)
SELECT
{[Measures].[Internet Sales Amount]} ON COLUMNS
,Generate
(
[MthsCountries] AS X
,
Order
(
Intersect
(
X.Current * [AllProds]
,[Top5Prods]
)
,[Measures].[Internet Sales Amount]
,bdesc
)
+
{X.Current * {[Product].[Product].[All].[RestOfProds]}}
) ON ROWS
FROM [Adventure Works];
如果您在同一维度中交叉连接多个层次结构,则只会显示有效组合。这称为自动存在,它解释了为什么第一个查询按您想要的方式工作。
当交叉连接来自不同维度的层次结构时,自动存在不会发生。我认为这解释了第二个查询中 returned 的奇怪组合。
尝试在 ON ROWS 定义的开头添加 NON EMPTY。然后它只会 return 具有 Internet Order Count 度量值的组合(无论列上的度量)。这是限制交叉连接的正确方法。
如果您不想在 Internet 订单计数上使用 NON EMPTY,那么您需要在不同的度量上使用 NonEmpty(, [Measures].[A Different Measure])?
编辑:看起来这个问题与自动存在无关,而是与每个国家/地区执行不同的 TopCount 有关。所以这个信息可能会帮助其他人,但不是这个问题的答案。
EXISTING
在命名集上使用时,并没有真正的区别,因为命名集是在布局轴成员之前创建的。在您的情况下, GENERATE
实际上只是创建静态集,然后在轴上的所有内容都只是交叉连接。
要使 TopCount
脚本正常工作,您需要处理一组中的所有 cross joins
,以便一起评估所有内容。我不确定,但您可以尝试以下操作:
WITH
SET [AllCountries] AS [Country].[Country].MEMBERS
SET [AllCats] AS [Product].[Category].[Category].MEMBERS
SET [Top5Cats] AS
Generate
(
[AllCountries] as a
,
{
(a.current , [Product].[Category].[All] ) //The ALL member
+
TopCount //The top 2 categories
(
NonEmpty((a.current * [AllCats] ) , (a.CURRENT, [Measures].[Internet Order Count]))
,2
,[Measures].[Internet Order Count]
)
}
+
{ //The rest of the members
a.current * [AllCats]
-
a.current *{
TopCount
(
NonEmpty([AllCats] , (a.CURRENT, [Measures].[Internet Order Count]))
,2
,[Measures].[Internet Order Count]
)
}
}
)
MEMBER [Product].[Category].[All].[RestOfProds] AS
Aggregate({(EXISTING {[AllCats]} - [Top5Cats])})
SELECT
{[Measures].[Internet Order Count]} ON COLUMNS,
[Top5Cats] ON ROWS
FROM [Adventure Works];
编辑:
如果你需要RestOfCats
成员,你可以添加这个代码。
SET [RestOfCats] AS
EXTRACT
(
{
[AllCountries] * [AllCats]
-
[Top5Cats]
},
[Product].[Category]
)
MEMBER [Product].[Category].[All].[RestOfCats] AS
Aggregate([RestOfCats])
编辑 2
继续您的示例,在定义中另外删除 'All' 成员。
SET [RestOfProds] AS
Extract
(
{[AllCountries] * [AllProds]} - [Top5Prods] - [AllCountries]*[Product].[Product].[All]
,[Product].[Product]
)
这似乎工作正常:
WITH
SET [AllCountries] AS
[Country].[Country].MEMBERS
SET [AllProds] AS
[Product].[Product].[Product].MEMBERS
SET [Top5Prods] AS
Generate
(
[AllCountries] AS a
,{
(
a.CurrentMember
,[Product].[Product].[All]
)
+
//The top x prods
a.CurrentMember
*
TopCount
(
[AllProds]
,5
,[Measures].[Internet Sales Amount]
)
}
)
MEMBER [Product].[Product].[All].[Other Products] AS
Aggregate
(
[Country].CurrentMember * [Product].[Product].[Product].MEMBERS
-
[Top5Prods]
)
SELECT
{[Measures].[Internet Sales Amount]} ON COLUMNS
,Hierarchize(
{
[Top5Prods]
,[AllCountries] * [Product].[Product].[All].[Other Products]
}
) ON ROWS
FROM [Adventure Works];