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. 2016huasacm暑假集训训练四 递推_C

    题目链接:http://acm.hust.edu.cn/vjudge/contest/125308#problem/C 题意:给你一个高为n ,宽为m列的网格,计算出这个网格中有多少个矩形  这个题只 ...

  2. php_cz

    post.php <?php require_once 'config.php'; $ddh=trim(htmlspecialchars($_POST['ddh'])); //支付宝交易号 $m ...

  3. win 10 常见问题

    Microsoft Edge Can't Open Local Domains IE Edge浏览器打不开本地站点 解决方法:解决方法

  4. windows 查看端口占用以及关闭该进程

    win+r -> 输入cmd netstat -ano 找到占用端口进程的pid control+shift+esc 打开 任务管理器 menu->'查看'->'选择列->勾选 ...

  5. 制作手机相册 全屏滚动插件fullpage.js

    今天是端午自己做了一个小的送祝福链接  这里用到了fullpage插件 $('#container').fullpage({ navigation: false,        //navigatio ...

  6. 谈一谈php://filter的妙用

    php://filter是PHP中独有的协议,利用这个协议可以创造很多"妙用",本文说几个有意思的点,剩下的大家自己下去体会.本来本文的思路我上半年就准备拿来做XDCTF2016的 ...

  7. 无法安装MVC3,错误提示:安装KB2483190(vs10-kb2483190)出错

    原文:无法安装MVC3,错误提示:安装KB2483190(vs10-kb2483190)出错 无法安装MVC3,错误提示:安装KB2483190(vs10-kb2483190)出错. 安装指导:&qu ...

  8. centos 下pip 安装snappy 系列问题记录

    试用sud o pip提示找不到pip命令,不加sudo可以找到,这时候需要使用whereis 去看pip命令的路径 sudo + pip完整路径即可 安装python  snappy 失败提示: s ...

  9. Spring注解@Resource和@Autowired区别对比

    转载:http://www.cnblogs.com/think-in-java/p/5474740.html @Resource和@Autowired都是做bean的注入时使用,其实@Resource ...

  10. 简单理解js的this

    js的this是什么?关于这个东西,博客园里面有太多的解释了,不过,本人看了一下,感觉对this解释的有点复杂了,因此,本人在此给this一个简单易于理解的定义. this其实是js的一个对象,至于是 ...