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语句所示:

 select *
from [dbo].[Fact_People_Money] inner join [dbo].[DIM_People] on [Fact_People_Money].DIM_PeopleID=[DIM_People].ID
inner join [dbo].[Fact_PeopleVehicle] on [DIM_People].ID=[Fact_PeopleVehicle].DIM_PeopleID
inner join [dbo].[DIM_Vehcile] on [Fact_PeopleVehicle].DIM_VehicleID=[DIM_Vehcile].ID
inner join [dbo].[Fact_Vehicle_Color] on [DIM_Vehcile].ID=[Fact_Vehicle_Color].DIM_VehicleID
inner join [dbo].[DIM_VehicleColor] on [Fact_Vehicle_Color].DIM_VehicleColorID=[DIM_VehicleColor].ID
where [DIM_VehicleColor].VehicleColor=N'Red'

图3

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

 select sum([Fact_People_Money].[Money]) as [TotalMoney]
from [dbo].[Fact_People_Money] inner join [dbo].[DIM_People] on [Fact_People_Money].DIM_PeopleID=[DIM_People].ID
inner join [dbo].[Fact_PeopleVehicle] on [DIM_People].ID=[Fact_PeopleVehicle].DIM_PeopleID
inner join [dbo].[DIM_Vehcile] on [Fact_PeopleVehicle].DIM_VehicleID=[DIM_Vehcile].ID
inner join [dbo].[Fact_Vehicle_Color] on [DIM_Vehcile].ID=[Fact_Vehicle_Color].DIM_VehicleID
inner join [dbo].[DIM_VehicleColor] on [Fact_Vehicle_Color].DIM_VehicleColorID=[DIM_VehicleColor].ID
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语句:

 select sum([Money]) as [TotalMoney]
from
(
select distinct [Fact_People_Money].DIM_PeopleID,[Fact_People_Money].[Money]
from [dbo].[Fact_People_Money] inner join [dbo].[DIM_People] on [Fact_People_Money].DIM_PeopleID=[DIM_People].ID
inner join [dbo].[Fact_PeopleVehicle] on [DIM_People].ID=[Fact_PeopleVehicle].DIM_PeopleID
inner join [dbo].[DIM_Vehcile] on [Fact_PeopleVehicle].DIM_VehicleID=[DIM_Vehcile].ID
inner join [dbo].[Fact_Vehicle_Color] on [DIM_Vehcile].ID=[Fact_Vehicle_Color].DIM_VehicleID
inner join [dbo].[DIM_VehicleColor] on [Fact_Vehicle_Color].DIM_VehicleColorID=[DIM_VehicleColor].ID
where [DIM_VehicleColor].VehicleColor=N'Red'
) as t

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

  1. 在SQL SERVER中获取表中的第二条数据

    在SQL SERVER中获取表中的第二条数据, 思路:先根据时间逆排序取出前2条数据作为一个临时表,再按顺时排序在临时表中取出第一条数据 sql语句如下: select top 1 * from(se ...

  2. 查看hive中某个表中的数据、表结构及所在路径

    查看hive中action_data_myisam表中的数据.表结构及所在路径 1.客户端进入hive环境:hive 2.查看表数据,鉴于数据量大,这里只显示前五条:select * from act ...

  3. 在Action中获取表单提交数据

    -----------------siwuxie095 在 Action 中获取表单提交数据 1.之前的 Web 阶段是提交表单到 Servlet,在其中使用 Request 对象 的方法获取数据 2 ...

  4. 备忘:MySQL中修改表中某列的数据类型、删除外键约束

    -- MySQL中修改表中某列的数据类型 ALTER TABLE [COLUMN] 表名 MODIFY 列名 列定义; -- 删除外键约束 SHOW CREATE TABLE 表名; -- 复制CON ...

  5. mybatis报错:查询一对多或多对多时只返回一条数据的问题

    问题: 使用映射文件实现查询一对多或多对多时只返回一条数据问题 解决方法: 导致这种情况出现的问题是因为两个表中的主键是一样所以出现了数据覆盖问题. 解决方式一:修改数据库表中的主键(这种方法比较麻烦 ...

  6. 【BIEE】04_当维度表中的维不存在事实表中,需要展示所有维度并且数据类展示为0

    有时候,我们往往会存在这样的需求 例如:事实表的数据如下 EMP_FACT表示事实表,DIM_LEVEL是维度表 预期效果:(根据员工信息,分析各等级员工工资与员工个数) 我们在BIEE报表中新建报表 ...

  7. BI中事实表和维度表的定义

    一个典型的样例是,把逻辑业务比作一个立方体,产品维.时间维.地点维分别作为不同的坐标轴,而坐标轴的交点就是一个详细的事实.也就是说事实表是多个维度表的一个交点.而维度表是分析事实的一个窗体. 首先介绍 ...

  8. BI中事实表与维度表的定义

    一个典型的例子是,把逻辑业务比作一个立方体,产品维.时间维.地点维分别作为不同的坐标轴,而坐标轴的交点就是一个具体的事实.也就是说事实表是多个维度表的一个交点.而维度表是分析事实的一个窗口. 首先介绍 ...

  9. C#中去掉表中重复的数据

    /// <summary> /// 去掉表中重复的数据  int /// </summary> /// <param name="SourceTable&quo ...

随机推荐

  1. java并发编程(九)死锁

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/17200937 大部分代码并不容易产生死锁,死锁可能在代码中隐藏相当长的时间,等待不常见的条 ...

  2. JS全兼容检测浏览器类型及版本

    直接上代码: <script> var browser = (function () { var isIE6 = /msie 6/i.test(navigator.userAgent); ...

  3. Struts2+jQuery+Json零配置实现ajax

    (一)Jsp页面代码 <%@ page language="java" import="java.util.*" pageEncoding="U ...

  4. Google 云计算中的 GFS 体系结构

          google 公司的很多业务具有数据量巨大的特点,为此,google 公司研发了云计算技术.google 云计 算结构中的 google 文件系统是其云计算技术中的三大法宝之一.本文主要介 ...

  5. asp.net identity 2.2.0 在WebForm下的角色启用和基本使用(三)

    角色管理功能: 界面部分: <%@ Page Title="" Language="C#" MasterPageFile="~/Site.mas ...

  6. 合并多个工作薄workbooks到一个工作薄workbook

    微软示例教程 微软示例教程 Sub MergeAllWorkbooks() Dim SummarySheet As Worksheet Dim FolderPath As String Dim NRo ...

  7. 几何服务,cut功能测试

    关于几何服务 几何服务用于辅助应用程序执行各种几何计算,如缓冲区.简化.面积和长度计算以及投影.在 ArcGIS Server 管理器中启动几何服务之后,您才能够在应用程序开发过程中使用该服务. 问题 ...

  8. asp.net mvc 表单相关

    1. <form action="/controller/action" method="post"> ... </form> *act ...

  9. java测试框架整理

    Test: Junit4+Hamcrest 不多说了,就靠着两个 import static org.hamcrest.Matchers.equalTo; import static org.juni ...

  10. if语句中的判断条件(nginx)

    if语句中的判断条件   正则表达式匹配:     ==:等值比较;     ~:与指定正则表达式模式匹配时返回"真",判断匹配与否时区分字符大小写:     ~*:与指定正则表达 ...