MDX - 获取总和而不是单个值
MDX - Getting the sum instead of individual values
我的数据是这样的:
ID |PersonID |CompanyID |DateID |Throughput |AmountType
33F467AC-F35B-4F24-A05B-FC35CF005981 |7 |53 |200802 |3 |0
04EE0FF0-511D-48F5-AA58-7600B3A69695 |18 |4 |201309 |5 |0
AB058AA5-6228-4E7C-9469-55827A5A34C3 |25 |69 |201108 |266 |0
大约有一百万行。列名 *ID 引用其他表,因此它们可以用作维度。
我有一个 OLAP 多维数据集,其中吞吐量列作为度量,其余列作为维度。
我有一个应该计算四分位数的 MDX 查询,此处描述并解决了查询的其他问题:。
当我过滤一年时,计算工作正常,但当我过滤两年时,结果是这两年的总和。我用一个例子来演示。我已将查询简化为仅显示行数,因为它仍然会出现同样的问题。
一年的 MDX 查询如下所示:
WITH
SET selection as ({[Dates].[Year].&[2014]})
SET [NonEmptyIds] AS
NonEmpty(
[ThroughputID].[ID].[Id].ALLMEMBERS,
{[Measures].[Throughput]} * [selection]
)
SET [ThroughputData] AS
ORDER
(
[NonEmptyIds],
[Measures].[Throughput],
BASC
)
MEMBER [Measures].[RowCount] AS COUNT (ThroughputData)
SELECT
selection ON 0,
{[Measures].[RowCount]}
ON 1
FROM [Throughput]
以上查询的结果是:
|2014
RowCount |116 979
如果我将选择部分更改为在 2015 年筛选:
SET selection as ({[Dates].[Year].&[2015]})
我得到这个结果:
|2015
RowCount |68 038
然后,如果我更改选择部分以同时过滤 2014 年和 2015 年:
SET selection as ({[Dates].[Year].&[2014],[Dates].[Year].&[2015]})
我得到这个结果:
|2014 |2015
RowCount |185 017 |185 017
如116 979 + 68 038 = 185 017,这两年都是各年的总和。
有谁知道我在查询中做错了什么?
我不明白您为什么要以基于 MDX 的复杂方式使用会话定义的集合和度量(WITH...)来计算它。为什么不简单地在多维数据集中创建一个基于 COUNT 的度量,以您的事实 table 的行为来源,并让 [Dates] 维度对其进行切片?
然后您的 MDX 将简化为(例如):
SELECT
Measures.[YourCountMeasure] ON 0,
[Dates].[Year].Members ON 1
FROM Throughput
按年份的切片将在立方体中定义。
原来如此,问题就在这里:
SET [NonEmptyIds] AS
NonEmpty(
[ThroughputID].[ID].[Id].ALLMEMBERS,
{[Measures].[Throughput]} * [selection]
)
这个集合被定义了一次。它使用 set [selection](两年)。它不会在您的 MDX 查询中多次重新评估。事实上,您在查询的轴上有 [Dates].[Years] 的单独成员,这不会使该集合为该成员重新计算 ("oh look, this set is also defined on the [Dates].[Years] hierarchy - I'd better slice it and recalculate the set based on the current member")。该集合仅评估一次。
像这样的简单 COUNT 措施可能会奏效:
WITH
MEMBER Measures.CountNonEmptyThings AS
COUNT(NonEmpty(
[ThroughputID].[ID].[Id].ALLMEMBERS,
[Measures].[Throughput]))
SELECT
Measures.CountNonEmptyThings ON 0,
[Dates].[Years].Members ON 1 -- or whatever set you like
FROM Throughput
这 会 为您放在轴上的多年中的每一年重新计算。
当集合 Selection
中同时包含年份 2014
和 2015 时,则
NonEmpty(
[ThroughputID].[ID].[Id].ALLMEMBERS,
{[Measures].[Throughput]} * {[Dates].[Year].&[2014], [Dates].[Year].&[2015]}
)
以上是什么意思
给我一组 2014 年和 2015 年非空的 ID
由于每年对应的 ID 集是不同的(我猜),所以它们会被加起来!
由于您给出了示例代码,我对集合的用法没有任何意见,但您必须对代码进行大量修改才能获得当前计数。
WITH
SET selection as
{
[Dates].[Year].[Year].&[2015],
[Dates].[Year].[Year].&[2014]
}
MEMBER [Measures].[RowCount] AS
COUNT (
NonEmpty(
[ThroughputID].[ID].[Id].ALLMEMBERS,
[Measures].[Throughput]
)
)
SELECT
RowCount ON 0,
selection ON 1
FROM [Throughput]
长话短说:由于集合是静态的并且当前上下文不会更改其内容,因此不应在计算中使用它们。
我上面所做的不是在我的计算中引用集合,而是引用当前年份(在范围内)来获取 ID,而不是将其放入另一个命名集合(这又是静态的),把它放在一个成员的计算中。
希望对您有所帮助。
SEBTHU 的回答在我看来还不错。我认为不需要在您的自定义度量中使用 currentmember
函数。
这是针对 AdvWrks
多维数据集的等效脚本:
WITH
SET [YearSet] AS
{
[Date].[Calendar Year].&[2007]
,[Date].[Calendar Year].&[2008]
}
MEMBER [Measures].[RowCount] AS
Count
(
NonEmpty
(
[Customer].[Customer].[Customer]
,[Measures].[Internet Sales Amount]
)
)
SELECT
[Measures].[RowCount] ON 0
,[YearSet] ON 1
FROM [Adventure Works];
这就是上面的returns即不是静态的:
您还可以使用 SUM
函数与 IIF
的组合来构建这样的计数度量 - 在某些情况下它可以很快:
WITH
SET [YearSet] AS
{
[Date].[Calendar Year].&[2007]
,[Date].[Calendar Year].&[2008]
}
MEMBER [Measures].[RowCount] AS
Count
(
NonEmpty
(
[Customer].[Customer].[Customer]
,[Measures].[Internet Sales Amount]
)
)
MEMBER [Measures].[RowCountFAST] AS
Sum
(
[Customer].[Customer].[Customer]
,IIF
(
[Measures].[Internet Sales Amount] = 0
,null
,1
)
)
SELECT
{
[Measures].[RowCount]
,[Measures].[RowCountFAST]
} ON 0
,[YearSet] ON 1
FROM [Adventure Works];
以上结果:
此替代方法适用于您的场景:
WITH
MEMBER [Measures].[CountNonEmptyThings] AS
Sum
(
[ThroughputID].[ID].[Id]
,IIF
(
[Measures].[Throughput] = 0
,NULL
,1
)
)
SELECT
[Measures].[CountNonEmptyThings] ON 0
,[Dates].[Years].MEMBERS ON 1
FROM [Throughput];
我的数据是这样的:
ID |PersonID |CompanyID |DateID |Throughput |AmountType
33F467AC-F35B-4F24-A05B-FC35CF005981 |7 |53 |200802 |3 |0
04EE0FF0-511D-48F5-AA58-7600B3A69695 |18 |4 |201309 |5 |0
AB058AA5-6228-4E7C-9469-55827A5A34C3 |25 |69 |201108 |266 |0
大约有一百万行。列名 *ID 引用其他表,因此它们可以用作维度。
我有一个 OLAP 多维数据集,其中吞吐量列作为度量,其余列作为维度。
我有一个应该计算四分位数的 MDX 查询,此处描述并解决了查询的其他问题:
当我过滤一年时,计算工作正常,但当我过滤两年时,结果是这两年的总和。我用一个例子来演示。我已将查询简化为仅显示行数,因为它仍然会出现同样的问题。 一年的 MDX 查询如下所示:
WITH
SET selection as ({[Dates].[Year].&[2014]})
SET [NonEmptyIds] AS
NonEmpty(
[ThroughputID].[ID].[Id].ALLMEMBERS,
{[Measures].[Throughput]} * [selection]
)
SET [ThroughputData] AS
ORDER
(
[NonEmptyIds],
[Measures].[Throughput],
BASC
)
MEMBER [Measures].[RowCount] AS COUNT (ThroughputData)
SELECT
selection ON 0,
{[Measures].[RowCount]}
ON 1
FROM [Throughput]
以上查询的结果是:
|2014
RowCount |116 979
如果我将选择部分更改为在 2015 年筛选:
SET selection as ({[Dates].[Year].&[2015]})
我得到这个结果:
|2015
RowCount |68 038
然后,如果我更改选择部分以同时过滤 2014 年和 2015 年:
SET selection as ({[Dates].[Year].&[2014],[Dates].[Year].&[2015]})
我得到这个结果:
|2014 |2015
RowCount |185 017 |185 017
如116 979 + 68 038 = 185 017,这两年都是各年的总和。
有谁知道我在查询中做错了什么?
我不明白您为什么要以基于 MDX 的复杂方式使用会话定义的集合和度量(WITH...)来计算它。为什么不简单地在多维数据集中创建一个基于 COUNT 的度量,以您的事实 table 的行为来源,并让 [Dates] 维度对其进行切片?
然后您的 MDX 将简化为(例如):
SELECT
Measures.[YourCountMeasure] ON 0,
[Dates].[Year].Members ON 1
FROM Throughput
按年份的切片将在立方体中定义。
原来如此,问题就在这里:
SET [NonEmptyIds] AS
NonEmpty(
[ThroughputID].[ID].[Id].ALLMEMBERS,
{[Measures].[Throughput]} * [selection]
)
这个集合被定义了一次。它使用 set [selection](两年)。它不会在您的 MDX 查询中多次重新评估。事实上,您在查询的轴上有 [Dates].[Years] 的单独成员,这不会使该集合为该成员重新计算 ("oh look, this set is also defined on the [Dates].[Years] hierarchy - I'd better slice it and recalculate the set based on the current member")。该集合仅评估一次。
像这样的简单 COUNT 措施可能会奏效:
WITH
MEMBER Measures.CountNonEmptyThings AS
COUNT(NonEmpty(
[ThroughputID].[ID].[Id].ALLMEMBERS,
[Measures].[Throughput]))
SELECT
Measures.CountNonEmptyThings ON 0,
[Dates].[Years].Members ON 1 -- or whatever set you like
FROM Throughput
这 会 为您放在轴上的多年中的每一年重新计算。
当集合 Selection
中同时包含年份 2014
和 2015 时,则
NonEmpty(
[ThroughputID].[ID].[Id].ALLMEMBERS,
{[Measures].[Throughput]} * {[Dates].[Year].&[2014], [Dates].[Year].&[2015]}
)
以上是什么意思
给我一组 2014 年和 2015 年非空的 ID
由于每年对应的 ID 集是不同的(我猜),所以它们会被加起来!
由于您给出了示例代码,我对集合的用法没有任何意见,但您必须对代码进行大量修改才能获得当前计数。
WITH
SET selection as
{
[Dates].[Year].[Year].&[2015],
[Dates].[Year].[Year].&[2014]
}
MEMBER [Measures].[RowCount] AS
COUNT (
NonEmpty(
[ThroughputID].[ID].[Id].ALLMEMBERS,
[Measures].[Throughput]
)
)
SELECT
RowCount ON 0,
selection ON 1
FROM [Throughput]
长话短说:由于集合是静态的并且当前上下文不会更改其内容,因此不应在计算中使用它们。
我上面所做的不是在我的计算中引用集合,而是引用当前年份(在范围内)来获取 ID,而不是将其放入另一个命名集合(这又是静态的),把它放在一个成员的计算中。
希望对您有所帮助。
SEBTHU 的回答在我看来还不错。我认为不需要在您的自定义度量中使用 currentmember
函数。
这是针对 AdvWrks
多维数据集的等效脚本:
WITH
SET [YearSet] AS
{
[Date].[Calendar Year].&[2007]
,[Date].[Calendar Year].&[2008]
}
MEMBER [Measures].[RowCount] AS
Count
(
NonEmpty
(
[Customer].[Customer].[Customer]
,[Measures].[Internet Sales Amount]
)
)
SELECT
[Measures].[RowCount] ON 0
,[YearSet] ON 1
FROM [Adventure Works];
这就是上面的returns即不是静态的:
您还可以使用 SUM
函数与 IIF
的组合来构建这样的计数度量 - 在某些情况下它可以很快:
WITH
SET [YearSet] AS
{
[Date].[Calendar Year].&[2007]
,[Date].[Calendar Year].&[2008]
}
MEMBER [Measures].[RowCount] AS
Count
(
NonEmpty
(
[Customer].[Customer].[Customer]
,[Measures].[Internet Sales Amount]
)
)
MEMBER [Measures].[RowCountFAST] AS
Sum
(
[Customer].[Customer].[Customer]
,IIF
(
[Measures].[Internet Sales Amount] = 0
,null
,1
)
)
SELECT
{
[Measures].[RowCount]
,[Measures].[RowCountFAST]
} ON 0
,[YearSet] ON 1
FROM [Adventure Works];
以上结果:
此替代方法适用于您的场景:
WITH
MEMBER [Measures].[CountNonEmptyThings] AS
Sum
(
[ThroughputID].[ID].[Id]
,IIF
(
[Measures].[Throughput] = 0
,NULL
,1
)
)
SELECT
[Measures].[CountNonEmptyThings] ON 0
,[Dates].[Years].MEMBERS ON 1
FROM [Throughput];