SSAS维度上有多个表的注意事项

在Sql Server Analysis Service中维度上有多张表(大于一张表)时,一定要注意将第二张表开始用到维度属性中的KeyColumns下的NullProcessing要设置为UnknownMember,并且一定要将外层表(在表关联中被其它表指向的表就叫外层表)中和内层表(在表关联中指向其它表的表就叫内层表)关联的字段作为维度属性,并且在维度属性关系中要设置这个和内层表关联的属性来指向外层表中其它的属性。这是为什么呢?我们来看下面这个例子。

现在我们有一个维度叫V Fact ADT IPD Encounter,其中用到了两张表V_Fact_ADT_IPD_Encounter和V_Dim_MedicalGroup,其中第一张表V_Fact_ADT_IPD_Encounter和事实表通过字段Visit ID直接关联(维度用法常规),而第二张表V_Dim_MedicalGroup和表V_Fact_ADT_IPD_Encounter通过字段Medical Group Code关联从而间接和事实表产生关联,在维度中字段Visit ID、Patient Name来自第一张表V_Fact_ADT_IPD_Encoun,字段Medical Group Code、Medical Group Description来自第二张表V_Dim_MedicalGroup,所以本例中V_Fact_ADT_IPD_Encounter就是我们上面所说的内层表,V_Dim_MedicalGroup就是我们上面所说的外层表,整个维度的结构如下图所示:

现在如果内层表V_Fact_ADT_IPD_Encounter中有数据和外层表V_Dim_MedicalGroup中的数据关联不上,也就是说内层表V_Fact_ADT_IPD_Encounter中有几行数据的MedicalGroupCode字段和外层表V_Dim_MedicalGroup的MedicalGroupCode字段无法匹配,无法匹配的原因有如下两种:

  • MedicalGroupCode字段的值不为null,但是两张表的MedicalGroupCode字段值不匹配。这时在处理CUBE的时候会报KeyNotFound错误,出现这个错误的原因也很简单,因为维度中属性Visit ID直接和事实表关联而且粒度最细,所以按道理来说Visit ID属性的每一个值都应该能找到维度中对应的其它属性值,而现在由于内层表V_Fact_ADT_IPD_Encounter中有几行数据在外层表V_Dim_MedicalGroup中找不到对应的数据行,就导致有Visit ID的属性值找不到外层表V_Dim_MedicalGroup中Medical Group Code、Medical Group Description这两个属性,所以CUBE处理时就报KeyNotFound错误。那么现在我们如下图所示将外层表V_Dim_MedicalGroup中Medical Group Code、Medical Group Description两个属性的KeyColumns的NullProcessing设置为UnknownMember,那么内层表V_Fact_ADT_IPD_Encounter中在外层表V_Dim_MedicalGroup中找不到对应数据的数据行都会被归类到外层表V_Dim_MedicalGroup中Medical Group Code、Medical Group Description这两个属性的UnknownMember下,CUBE处理的时候也就不会报错了。那么如果维度中存在多张表时,是不是将外层表用到属性的KeyColumns的NullProcessing设置为UnknownMember就万事大吉呢了?答案是不是,请接着看下面一种情况。

    

  • 内层表V_Fact_ADT_IPD_Encounter的MedicalGroupCode字段有null值,导致两张表有数据行无法匹配。这时如果维度中有外层表V_Dim_MedicalGroup中的字段作为了维度属性,那么在默认情况下处理维度V Fact ADT IPD Encounter时,SSAS会直接将内层表V_Fact_ADT_IPD_Encounter中MedicalGroupCode字段为null的数据行忽略掉,会导致来自内层表V_Fact_ADT_IPD_Encounter的两个维度属性Visit ID、Patient Name的属性值个数变少,变少的个数就是内层表V_Fact_ADT_IPD_Encounter中MedicalGroupCode字段为null的数据行数。这时必须要将外层表V_Dim_MedicalGroup中与内层表V_Fact_ADT_IPD_Encounter发生关联的属性字段MedicalGroupCode作为维度属性,

    

       并且在维度关系中设置MedicalGroupCode属性指向外层表V_Dim_MedicalGroup的其它维度属性(在本例中就是设置MedicalGroupCode属性指向MedicalGroupDescription属性)

       

这样至少在处理维度V Fact ADT IPD Encounter时,SSAS不会将内层表V_Fact_ADT_IPD_Encounter中MedicalGroupCode字段为null的数据行忽略掉了,但是在处理维度时会报错,原因是由于内层表Fact_ADT_IPD_Encounter中MedicalGroupCode字段为null的数据行无法匹配外层表V_Dim_MedicalGroup的数据行,导致外层表的两个维度属性Medical Group Code和Medical Group Description找不到KeyColumns的值,所以这时我们还需要将维度属性设置中的KeyNotFound选项设置为IgnoreError,这样在处理维度V Fact ADT IPD Encounter时就不会报KeyNotFound错误了。同时别忘了还是要像上面一点提到的一样,我们还要将外层表V_Dim_MedicalGrou用到的属性Medical Group Code、Medical Group Description的KeyColumns的NullProcessing设置为UnknownMember,那么在处理维度后内层表V_Fact_ADT_IPD_Encounter中MedicalGroupCode字段为null的数据行都会被归类到外层表V_Dim_MedicalGroup中Medical Group Code、Medical Group Description这两个属性的UnknownMember下,达到了我们预期的结果。

 

综上所述结合上面我们讨论的两点,在维度中用到多张数据表时,一定要保证外层表中和内层表发生关联的字段设置成了维度属性,同时在属性关系中要设置外层表中和内层表发生关联的维度属性指向外层表中用到的其它维度属性,而且要保证所有外层表的维度属性的KeyColumns的NullProcessing设置为了UnknownMember,这样内层表无法和外层表发生匹配的数据行才会被正确归类到UnknownMember中去,得到我们想要的结果。

原文地址:https://www.cnblogs.com/OpenCoder/p/4798639.html