当某些行不存在时如何计算平均值?

how to calculate average when some rows does not exist?

当某些值为 NULL 时,请帮助创建平均值

事实table:

立方体:

SELECT NON EMPTY {[Measures].[Score]} * [Date].[Month].allmembers ON COLUMNS
,{[Name].[name].allmembers} ON ROWS
FROM Test

问题:

当我计算平均值时,NULL 值被排除在外。我尝试了 COALESCEEMPTY(),但无论如何都无法正确计算平均值。 Score=0 不正确的月份的平均值。代码如下:

WITH
MEMBER [Measures].[DateCount] AS DISTINCTCOUNT([Data].[date].[date])
MEMBER [Measures].[ScoreX] AS COALESCEEMPTY([Measures].[Score],0)
MEMBER [Measures].[DateCountX] AS COALESCEEMPTY([Measures].[DateCount],0)
MEMBER [Measures].[AvgScore] AS IIF([Measures].[DateCountX]=0,0,[Measures].[ScoreX]/[Measures].[DateCountX])
 SELECT NON EMPTY {[Measures].[AvgScore]} * [Date].[Month].allmembers ON COLUMNS
 ,{[Name].[name].allmembers} ON ROWS
 FROM Test

请帮忙寻找解决方法。

您的事实 table 需要用 0 表示每个缺少名称的月份。你可以用一个普通的-table-表达式来做到这一点。

declare @facttable table(name varchar(10),date datetime,score int);

insert into @facttable(name,date,score)
values
    ('a1','2015/01/01',15),
    ('a2','2015/01/01',30),
    ('a3','2015/01/01',26),
    ('a1','2015/02/01',20),
    ('a3','2015/02/01',14),
    ('a4','2015/02/01',45),
    ('a5','2015/02/01',3)



;

with fact_cte as(

    select
        tDistinctNames.DistinctName AS Name,
        tDistinctDates.DistinctDate AS Date,
        ISNULL(t.Score,0) AS Score

    from 
        (select distinct name as DistinctName from @facttable) tDistinctNames
            cross join
        (select distinct date as DistinctDate from @facttable) tDistinctDates

            left outer join @facttable t on 
                t.name = tDistinctNames.DistinctName AND
                t.date = tDistinctDates.DistinctDate

)
select *
from fact_cte

结果是这样的:

Name    Date    Score
a1  2015-01-01 00:00:00.000 15
a2  2015-01-01 00:00:00.000 30
a3  2015-01-01 00:00:00.000 26
a4  2015-01-01 00:00:00.000 0
a5  2015-01-01 00:00:00.000 0
a1  2015-02-01 00:00:00.000 20
a2  2015-02-01 00:00:00.000 0
a3  2015-02-01 00:00:00.000 14
a4  2015-02-01 00:00:00.000 45
a5  2015-02-01 00:00:00.000 3

可能像下面这样:

WITH 
MEMBER [Measures].[Score X] AS
  IIF(
    [Measures].[Data Count]=0
    ,0
    ,[Measures].[Data Count]
  )
MEMBER [Measures].[Data Count X] AS
  COUNT(
    [name].[name].CURRENTMEMBER
    *[Measures].[Score X]
  )
MEMBER [Measures].[Avg Score] AS
  DIVIDE(
    [Measures].[Score]
   ,[Measures].[Data Count X]
  )
...
...

如 Tab 所述,您可以对上面的第一个计算成员使用函数 COALESCEEMPTY

WITH 
MEMBER [Measures].[Score X] AS
  COALESCEEMPTY(
    [Measures].[Data Count]
    ,0)
MEMBER [Measures].[Data Count X] AS
  COUNT(
    [name].[name].CURRENTMEMBER
    *[Measures].[Score X]
  )
MEMBER [Measures].[Avg Score] AS
  DIVIDE(
    [Measures].[Score]
   ,[Measures].[Data Count X]
  )
...
...

最终的解决方案是这样的:

WITH

MEMBER Measures.[AvgScore] AS
Avg(
Descendants(
[Data].[Date].CurrentMember,
[Data].[Date].[Date]
),
coalesceempty(Measures.[Score],0)
)

 SELECT NON EMPTY {[Measures].[AvgScore]} * [Date].[Month].allmembers ON COLUMNS
 ,{[Name].[name].allmembers} ON ROWS

FROM Test