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. js入门篇之正则表达式基础

    定义:正则用于规定在文本中检索的内容,它是对字符串执行模式匹配的强大工具 RegExp(正则表达式) 对象的语法: new RegExp(pattern, attributes); pattern为一 ...

  2. mysql 查询成本

    SELECT SQL_NO_CACHE spu from dp_distributor_products_1_online where dpId > 15 AND dpId <= 60; ...

  3. PHP 获取当天 凌晨 时间戳常用代码

    echo strtotime(date('Y-m-d')); 获取明天凌晨的时间戳代码:echo strtotime(date('Y-m-d',strtotime('+1 day'))); 附上测试代 ...

  4. 关于type erasure

    哇,好久没有写blog了,再不写的话,blog的秘密都要忘记了,嘿嘿. 最近在试着参与一个开源项目,名字叫avim(A Vibrate IM),别想多了哟.地址是:https://github.com ...

  5. reg

    <div class="login-module"> <div class="wide c login"> <form id=&q ...

  6. Linux下安装性能测试负载机LG

    系统:CentOS release 6.6 (Final)  x86_64 安装包: 1.LRLG_00031.iso [Load Generator Standalone (Linux 64-bit ...

  7. CSP -- 运营商内容劫持(广告)的终结者

    缘由 我们公司最近手机端H5 经常受到商户和用户的投诉,说有广告并且导致不能正常进行操作,我们商户自己当然不会加广告了,但是商户和用户可不管这些了,就认为是我们的问题 探索发现根本 目前我们用的很多浏 ...

  8. linux-shell笔记

    1.当从windows拖到shell中无法传递文件时,多半可能没有权限,可用sudo rz来进行手动选择传递 2.连接虚拟机时,ssh 用户名@ip地址,然后会提示输入该虚拟机密码,输入密码即可连接 ...

  9. 【爬虫】BeautifulSoup之爬取百度贴吧的帖子

    在网上看到爬百度贴吧的例子,仿照写了一个用BeautifulSoup实现的,直接上代码吧 #coding:gbk import urllib2 from bs4 import BeautifulSou ...

  10. Wrestling Match---hdu5971(2016CCPC大连 染色法判断是否是二分图)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5971 题意:有n个人,编号为1-n, 已知X个人是good,Y个人是bad,m场比赛,每场比赛都有一个 ...