在事实表(维度建模数据仓库)的度量字段中,NULL值通常映射为0是什么原因?
答案 0 :(得分:15)
虽然你已经接受了另一个答案,但我会说使用NULL实际上是一个更好的选择,原因有两个。
第一个原因是,当存在NULL时,聚合返回“正确”答案(即用户倾向于期望的答案),但在使用零时给出“错误”答案。在这两个查询中考虑AVG()的结果:
-- with zero; gives 1.5
select SUM(measure), AVG(measure)
from
(
select 1.0 as 'measure'
union all
select 2.0
union all
select 3.0
union all
select 0
) dt
-- with null; gives 2
select SUM(measure), AVG(measure)
from
(
select 1.0 as 'measure'
union all
select 2.0
union all
select 3.0
union all
select null
) dt
如果我们假设此处的度量是“制造物品的天数”而NULL表示仍在生产的物品,则零给出错误的答案。同样的推理也适用于MIN()和MAX()。
第二个问题是,如果零是默认值,那么如何区分零作为默认值,零作为实际值?例如,考虑“欧元运费”的衡量标准,其中NULL表示客户自己接收订单,因此没有运费,零表示订单是免费运送给客户的。在不完全更改数据含义的情况下,不能使用零来替换NULL。你可以明显地认为,区别应该从其他方面明确(例如运输方法),但这会增加报告的复杂性并理解数据。
答案 1 :(得分:5)
这取决于你的建模,但一般来说,这是为了避免执行聚合的复杂性。在许多情况下,出于这些目的将NULL
视为0
是有意义的。
例如,在指定时间段内有NULL
个订单的客户。或者销售收入NULL
的销售人员(对他感到羞耻!)。
答案 2 :(得分:1)
主要原因是数据库将空格与空白或零区别对待,即使它们看起来像人类的空白或零眼。
以下是link关于同一主题的旧设计提示Ralph Kimball。
This blogpost讨论了避免措施中的空值并给出了一些建议。
答案 3 :(得分:0)
如果您打算在事实列上执行平均值,则应使用NULL而不是0。这是我认为NULLS在dwh事实或维度上的唯一时间
如果事实值未知/迟到,则最好留空。
MIN,MAX等集合函数在NULLS上工作只是忽略它们
(对于拉尔夫·金博尔的记录中的一位搭档,我打算在他的课程中说这个)
with goodf as
(
select 1 x
union all
select null
union all
select 4
)
select sum(x) sumx,min(x) minx,max(x) maxx,avg(cast(x as float)) avgx
from goodf
with badf as
(
select 1 x
union all
select 0 /* unknown */
union all
select 4
)
select sum(x) sumx,min(x) minx,max(x) maxx,avg(cast(x as float)) avgx
from badf
高于平均值的badf中的出现错误,因为它使用未知值的零作为字面值0