当某些行不存在时如何计算平均值?
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
当某些值为 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