使用POWERBI处理实际和预算的场景

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用POWERBI处理实际和预算的场景相关的知识,希望对你有一定的参考价值。

参考技术A 在介绍星形结构和powerbi最佳实践的时候,通常会被问到如何在同一个模型中处理预算和实际的问题?如果两者的粒度不一样怎么处理?通常我们不能通过简单的模型和关系处理这个问题,这需要复杂的DAX计算。但是这里的解决方案是,我们可以通过简单的模型解决这个问题!下面我们会通过一个案例来介绍解决过程,使用简单模型如何处理预算和实际粒度不同的问题。

事实表包含了发生的业务,其中保存了数值和可聚集的数值。下面这个FactResellerSales表就是一个事实表,DimProduct,DimDate,DimSalesTerritory,DimEmployee表。

建立模型的步骤:
1.把数据表加载到模型中
2.选择对于的表
3.移除DimSalesTerritory 和 DimEmployee之间的关系
4.把FactResellerSales 和 DimEmployee的关系设为活动的
5.使用FactResellerSales中的OrderDateKey和DimDate表的DateKey建立关系

上面这样的模型就是一个典型的星形模型。这个模型可以很好的处理销售相关的问题。但是,当我们要把另外一个不同粒度的表格添加到模型中的时候,似乎建立模型就有些困难。

举个栗子,这里我们使用销售指标来替代预算表,也是和业务表是不同粒度的。概念是一样的。我们要把一个粒度不同的表添加到模型中。销售指标表记录的是每个员工每个季度的销售指标数值。粒度是每员工每季度,而销售表的粒度是每员工每天每地区每产品。

如果你要对着两种表(指标和实际)添加到星形模型中,那么一般会遇到下面着两个问题:
1.如何把指标表连接到日期表?
2.如果我们建立了一个季度的维度表,那么如何把这个表和日期表关联?会形成一个雪花模型?

我们的目标是建立一个简单的模型来解决这个问题,也还是使用星形模型

虽然这里我们的销售指标表使用的粒度是基于季度的,我们还是可以把它连接到日期表。这样的方法可以避免额外的维度表以及产生雪花模型。有个需要考虑的是,我们要对每个季度确定一个默认的日期。例如,我们可以把每个季度的第一天设置为这个日期值。

要达到这个目标,我们需要在指标表建立一个列,下面的图中可见,我们使用了YYYYMMDD的格式。

通过以下步骤可以建立下面的列:
1.基于季度值,建立月份值
2.用月的第一天建立自定义列。

要建立季度一个月的值,我们使用下面着公式即可以完成:

[图片上传中...(-aa0d4d-1565855207069-0)]
这个计算我们放在Power Query Editor中完成。

第二步就是在这个基础上建立一个DateKey列。

这里,我们要确保的是,月份值都是两位的长度,通过三个步骤可以完成:1.把值转换为文本 2.对该列添加前缀“0” 3.提取该列右边的两个位置的值。

把数值类型转换为文本:

把列添加前缀:

提取字符串末尾两位字符:

在对指标表添加了DateKey后,我们可以通过它连接到日期表和employee表,这里我们依旧是星形模型。

这里我们不需要使用双向的关系,或者把一个维度连接到另外一个维度。这个模型可以轻松解决我们关于预算和实际的问题。

下面简单的展示一些分析的案例,我们从处理实际和预算的场景中,建立了一些指标和报表。所有这些工作都不需要特别的DAX函数计算以及使用双向的关系等。之所以能这样实现,是基于正确的建立了数据模型。

这里我们只建立了两个计算,很简单,分别是bud vs act:

以及Bud vs Act %:

建立了如下这样的案例:

从Employee角度:

这里,我们展示了一个处理预算和实际情况的完整数据模型。这个模型继承了星形模型的全部优点,包括但是不限于如下:
1.不需要额外的建立关系。只需要在事实表和维度表之间建立简单的关系就可以了。
2.不需要使用双向的关系。
3.不需要使用多对多关系。
4.不需要使用复杂的DAX函数计算。
5.处理计算需求的时候,性能上会更优秀。

这模型仍然还有一些地方可以进行改进,例如,如果你要在更低的一个粒度上分析数据,你需要额外的一些考虑。例如,如果你需要在“天”的级别上分析数据(注意,我们的指标数据是基于季度的,而不是“天”),然后,你需要一些其他的计算。这个我们会在另外的时间探讨以下。

用PowerBI自定义函数批量处理复杂表格

参考技术A 这篇帖子缘起于在微博上的一个讨论:

原帖提出用PowerQuery来合并同一文件夹下所有工作簿中的所有工作表数据,我做了一个补充:

当时我没说清楚细节,所以有网友回复说:

其实我说的自定义函数也是基于Excel.Workbook()这个函数,只是区别在于:对于复杂表格,用Excel.Workbook()获取所有Excel文件中所有Sheets的数据后,我并不展开,而是就展开单个Sheet,进行处理,然后基于此建立函数,再把此函数应用到其他尚未展开的Sheets上去。

说起来比较抽象,用一个实际例子来演示下这个思路。

原始数据是类似下面这样的表格:

我们只需要提取红圈中的数据,将每一个表格都降维(压扁)变成一条单一的记录。
这样的表格有无数个,散布在N个Excel文件中M个Sheets中。

如下图所示,引入来自于文件夹的源之后,调用Excel.Workbook()函数,获取到所有表格的数据,并保存在Table中,不展开。

对于简单表格(或曰规范表格,也就是表格第一行是列字段,以后每一行都是一条完整的记录,没有合并单元格),可以直接展开【Data】列,把展开的表格第一行提升为标题,筛选掉其余不需要的表格标题行(不过我一般喜欢先把【Data】列的每一个Table都用Table.PromoteHeaders()函数来把表格第一行作为标题,然后再展开,这样就可以节省一些步骤且不容易出错),这样就得到所需数据了。

但是实际工作中,我们有很大几率遇到这个例子中这样的复杂表格,让我们再回顾下:

[图片上传失败...(image-827bcf-1583634863355)]
对于这样复杂的表格,如果直接展开第一步得到的【Data】列,得到的结果就是如上图中这样的N*M个表格依次从上至下排列形成的一个巨大且复杂无比的大表格(由于表格太大太复杂,我截图都不好截。有兴趣的可以找一个很复杂的表格来亲自试试看),这样的表格,根据我寡陋的见识,简直不知道如何处理才好。

所以在提取数据这一步,我的做法稍有不同:

这样,当我们展开【自定义】列时,就可以直接得到我们所需的数据了。

如果表格很规范,结构很简单,完全没必要用自定义函数,直接用Excel.Workbook()函数获取表格,然后展开(是否先把第一行提升为标题看个人喜欢)即可;如果遇到很复杂的表格,直接展开应该是行不通的,这时就需要化整为零,通过自定义函数先把单个表格的处理步骤封装起来,然后再对其他表格调用该函数即可。

以上是关于使用POWERBI处理实际和预算的场景的主要内容,如果未能解决你的问题,请参考以下文章

PowerBI – 如何设置流式数据报告?

谈一谈你在powerbi或者powerquery中学到的技能?以及怎么解决实际问题?

PowerBi的意义在哪里

powerbi详细数据只显示十行

善用兵者,藏于无形,90 分钟深度讲解最佳推广价值作品

图书写作计划-Power BI入门指南 图书大纲及写作概要