• SSAS中事实表中的数据如果因为一对多或多对多关系复制了多份,在维度上聚合的时候还是只算一份


    SSAS事实表中的数据,有时候会因为一对多或多对多关系发生复制变成多份,如下图所示:

    图1

    我们可以从上面图片中看到,在这个例子中,有三个事实表Fact_People_Money(此表用字段Money记录了每个人的薪水,比如上图中就记录了PeopleID为1的人的薪水为1000), Fact_PeopleVehicle(此表为人车关系表,记录了人和车之间的多对多关系,比如上图中就记录了PeopleID为1的张三拥有三辆车,分别为宝马、大众和奔驰), Fact_Vehicle_Color(此表为车与颜色关系表,记录了车与颜色之间的多对多关系,比如上图中就记录了宝马、奔驰和大众三辆车都是红色), 另外有三个维度表DIM_People(此表记录人的数据信息,比如上图中记录了ID为1的张三), DIM_Vehicle(此表记录车的数据信息,比如上图中记录了ID为1、2、3的三辆车宝马、大众、奔驰), DIM_VehicleColor(此表记录车颜色的信息,比如上图中记录了ID为1的红色)

    这三个事实表和三个维度表一共组成了两个Cube中的多对多关系:

    • 多对多1:由于事实表Fact_People_Money和事实表Fact_PeopleVehicle通过维度表DIM_People连接是一对多关系,维度表DIM_Vehicle和事实表Fact_PeopleVehicle之间也是一对多关系,所以事实表Fact_People_Money和维度表DIM_Vehicle在Cube中可以设置为多对多关系,其中中间事实表是Fact_PeopleVehicle。
    • 多对多2:由于从多对多1关系中我们知道了维度表DIM_Vehicle和事实表Fact_People_Money之间是多对多关系,而维度表DIM_Vehicle和维度表DIM_VehicleColor之间通过事实表Fact_Vehicle_Color关联也是多对多关系,因此我们可以在Cube中将维度DIM_VehicleColor和事实表Fact_People_Money设置为多对多关系,其中中间事实表是Fact_Vehicle_Color。

    在Cube中我们可以设置上面图中的维度关系如下:

    图2

    那么现在问题来了,在上面的图1中我们看到事实表Fact_People_Money中PeopleID为1、Money为1000的记录,在事实表Fact_PeopleVehicle中对应了三条记录分别为宝马、大众和奔驰。而从事实表Fact_Vehicle_Color的数据中我们可以知道宝马、大众和奔驰三辆车都对应维度表DIM_VehicleColor中ID为1的记录,所以这三辆车都是红色。那么直接通过Sql语句将DIM_VehicleColor inner join Fact_Vehicle_Color inner join DIM_Vehicle inner join Fact_PeopleVehicle inner join DIM_People inner join Fact_People_Money后,我们将得到三条记录,如下Sql语句所示:

    1 select * 
    2 from [dbo].[Fact_People_Money] inner join [dbo].[DIM_People] on [Fact_People_Money].DIM_PeopleID=[DIM_People].ID 
    3 inner join [dbo].[Fact_PeopleVehicle] on [DIM_People].ID=[Fact_PeopleVehicle].DIM_PeopleID 
    4 inner join [dbo].[DIM_Vehcile] on [Fact_PeopleVehicle].DIM_VehicleID=[DIM_Vehcile].ID 
    5 inner join [dbo].[Fact_Vehicle_Color] on [DIM_Vehcile].ID=[Fact_Vehicle_Color].DIM_VehicleID 
    6 inner join [dbo].[DIM_VehicleColor] on [Fact_Vehicle_Color].DIM_VehicleColorID=[DIM_VehicleColor].ID
    7 where [DIM_VehicleColor].VehicleColor=N'Red'

    图3

    执行上面的Sql语句得到了三条记录,表示的是拥有红色车的人,其实这三条记录都是同一个人也就是DIM_People 维度表中的张三,但是由于张三拥有三辆车,所以将所有表 inner join 之后得到了三条记录,如果直接聚合这三条记录然后sum事实表Fact_People_Money中的Money字段,将会得到拥有红色车的人薪水总共是3000,如下面语句和图片所示:

    1 select sum([Fact_People_Money].[Money]) as [TotalMoney] 
    2 from [dbo].[Fact_People_Money] inner join [dbo].[DIM_People] on [Fact_People_Money].DIM_PeopleID=[DIM_People].ID 
    3 inner join [dbo].[Fact_PeopleVehicle] on [DIM_People].ID=[Fact_PeopleVehicle].DIM_PeopleID 
    4 inner join [dbo].[DIM_Vehcile] on [Fact_PeopleVehicle].DIM_VehicleID=[DIM_Vehcile].ID 
    5 inner join [dbo].[Fact_Vehicle_Color] on [DIM_Vehcile].ID=[Fact_Vehicle_Color].DIM_VehicleID 
    6 inner join [dbo].[DIM_VehicleColor] on [Fact_Vehicle_Color].DIM_VehicleColorID=[DIM_VehicleColor].ID
    7 where [DIM_VehicleColor].VehicleColor=N'Red'

    图4

    但很明显这是错误的,因为这3000其实是将同一个人张三的薪水乘以了三倍得到的,而从事实表Fact_People_Money中我们可以知道张三的薪水是1000,所以像这样单纯的将所有表inner join起来聚合算拥有红色车的人的薪水总和是不正确的。

    那么我们可以从最上面图1中看到Cube中多对多2这个关系,将维度DIM_VehicleColor和事实表Fact_People_Money连接起来了,为多对多维度关系,那么如果用MDX语句,将维度DIM_VehicleColor中的红色去切割事实表Fact_People_Money中的度量值Money,来计算Cube中拥有红色车的人的薪水总和该是多少,会是什么结果呢? MDX语句和执行结果如下所示:

    select [Measures].[Money] on 0,
    non empty [DIM Vehicle Color].[Vehicle Color].&[Red] on 1 
    from [Local DW]

    图5

    可以看到Cube并没有像前面的Sql一样将拥有红色车的人张三的薪水乘以了三变为3000,而是正确的得到了结果1000。说明Cube在计算多对多和一对多关系的时候,考虑到了事实表数据实际可能会翻倍的情况,根据事实表Fact_People_Money中的PeopleID字段做了distinct处理,最终得到了正确的结果,相当于如下Sql语句:

     1 select sum([Money]) as [TotalMoney]
     2 from
     3 (
     4     select distinct  [Fact_People_Money].DIM_PeopleID,[Fact_People_Money].[Money]
     5     from [dbo].[Fact_People_Money] inner join [dbo].[DIM_People] on [Fact_People_Money].DIM_PeopleID=[DIM_People].ID 
     6     inner join [dbo].[Fact_PeopleVehicle] on [DIM_People].ID=[Fact_PeopleVehicle].DIM_PeopleID 
     7     inner join [dbo].[DIM_Vehcile] on [Fact_PeopleVehicle].DIM_VehicleID=[DIM_Vehcile].ID 
     8     inner join [dbo].[Fact_Vehicle_Color] on [DIM_Vehcile].ID=[Fact_Vehicle_Color].DIM_VehicleID 
     9     inner join [dbo].[DIM_VehicleColor] on [Fact_Vehicle_Color].DIM_VehicleColorID=[DIM_VehicleColor].ID
    10     where [DIM_VehicleColor].VehicleColor=N'Red'
    11 ) as t
  • 相关阅读:
    NYOJ 38布线问题
    NYOJ 106背包问题
    基于贪心算法的几类区间覆盖问题 nyoj 12喷水装置(二) nyoj 14会场安排问题
    HDOJ 2546饭卡(01背包问题)
    FBI树-数据结构(二叉树)
    二叉树遍历(flist)(二叉树,已知中序层序,求先序)
    求先序排列(二叉树已知中序和后序,求先序)
    滑雪(dp)
    Python——plot可视化数据,作业8(python programming)
    数据库SQL语言学习----左外连接,右外连接,外连接,自然连接的形象对比
  • 原文地址:https://www.cnblogs.com/OpenCoder/p/6235037.html
Copyright © 2020-2023  润新知