完成了数据整理后,进入下一个阶段——数据建模,即定义数据表之间的关系。图2.4.1为导入成功后的数据模型,在模型视图下,Power BI已经自动建立了大部分数据关系。
图2.4.1
但DimDate表与FactSales表之间仍需要手动建立关系,这是因为表中没有“Date”字段。另外,Sales表中有“OrderDate”“ShipDate”两个日期字段,而Power BI不知道如何建立关系。
用户只需手动将DimDate表中的“Date”字段拖曳至FactSales表的“OrderDate”字段上方即可,之后两张表之间就形成了一对多的关系。这与Excel中的Vlookup函数功能相似,但其操作简单,且不影响报表性能,如图2.4.2所示。注意,还有一条虚线连接了“Date”与“OrderDate”字段,代表非激活的关系。在Power BI中,任何两张表之间,只能同时最多存在一个激活关系。
图2.4.2
当模型中的表数量过多时,会导致表之间的关联变得复杂,不利于用户分析和理解表之间的关系。为此,新版Power BI提供了局部视图功能,单击图2.4.1下方的“+”按钮,即可添加一个新栏“Geo”。将表“DimGeography”从右侧面板中拖曳至窗口的中央区域,并在该表上单击鼠标右键,在弹出的快捷菜单中单击“添加相关表”命令,如图2.4.3所示。
图2.4.3
添加完成后图中出现了FactSales表与DimEmploys表,相当于显示了整体关系图的局部视图,如图2.4.4所示。在复杂的模型中,局部视图为用户提供了便利。
图2.4.4
右击DimEmployee表,在弹出的快捷菜单中有“从关系图中删除”与“从模型中删除”两个命令,见图2.4.5。若选择“从关系图中删除”命令,则只是将报表从关系视图中移除,不影响整体的模型关系。若选择“从模型中删除”命令,则会影响现有的模型关系。如图2.4.6所示,在“Geo”视图中选择从模型中删除DimEmployee表后,DimEmployee表在模型中也消失了。
参照前文重新添加删除的表后,即可恢复该表,如图2.4.7所示。
图2.4.5
图2.4.6
图2.4.7
创建计算字段与度量也属于数据建模的范围。在本示例中会计算利润与利润率、消费者年龄组和销售年的同比。在Power BI的真实开发场景下,数据建模与可视化呈现可能是并行的。但为了条理更清晰,特此先介绍数据建模的内容。
首先在数据视图下观察销售表,见图2.4.8。SalesAmount字段代表销售额、NetSales字段代表利润,利润值即为NetSales的总和。
图2.4.8
参照图2.4.9,先选择报表视图,即单击“卡片图”选项,将“NetSales”字段拖入可视化图中,显示结果为“2.16百万”(单位是可以设置的)。这就是销售利润汇总结果。
图2.4.9
请留意“NetSales”字段旁的“Σ”图标,其代表该字段可被聚合。单击字段对应的下拉菜单,可见Power BI提供了多种聚合方式,如求和、平均值、最大值、最小值等,如图2.4.10所示。
图2.4.10
我们将这种不通过公式就直接可用于聚合的度量称为隐式度量,这与Excel中的数据透视表的用法一致。
下一步计算利润率。回到“数据”视图中,选中FactSales表。选择“表工具→新建列”命令。在公式栏中输入公式Proft%=DIVIDE([NetSales],[SalesAmount]),单击列工具中的%符号,就新建了一个名为Profit%的利润率计算字段,如图2.4.11所示。图中每一行利润率是该行记录对应的利润率。DIVID公式为非除以0公式,即分母不可以为0,防止除数为0出错。
图2.4.11
参照前文,再创建一个卡片图,将新创建的Profit%字段放入可视化图中,如图2.4.12所示。显然这个结果是错误的,因为它是利润的求和而非求平均值。
图2.4.12
根据前文已知,这个问题是由于默认的聚合导致的,将其聚合方式改为“平均值”,利润率即变为8.62%,如图2.4.13所示。
这个值看似正确,其实仍然是错误的。因为该值为所有利润率汇总的平均值,而正确的做法是先汇总利润(分子)和汇总销售数量(分母),再相除。这也是隐式度量的限制。为了得出正确的利润率,可以参照图2.4.14所示的方式创建3个度量:
图2.4.13
图2.4.14
注意: 在度量公式中,“'”后面的是Table信息,“[”后面的是字段名称。Power BI有智能提示功能,按【Tab】键可以快速填充公式。Profit%度量是由Sales和Profit嵌套形成的。我们将这种通过公式完成的度量称之为显式度量。凡是显式度量,一定要使用Table[Field]指定字段名称,不能直接用[Field],否则容易产生计算错误。
参照图2.4.15,将创建的Profit%度量放入卡片图中,注意,在显性度量下拉菜单中不再有聚合选项,因为公式中的SUM函数已经明确了聚合方式为求和。13.38%是正确的平均利润值。
为方便读者理解,图2.4.16对比了两种计算利润方法的差别。显然,第一种计算方法的错误之处在于其直接计算每一行的平均利润%,而第二种计算方法是分子和分母分别聚合,再相除。
在通常情况下,建议用户优先使用显式度量,尤其对于涉及两个或以上变量的计算,以避免以上例子中不必要的错误。表2.4.1为隐式度量与显式度量的对比。
图2.4.15
图2.4.16
表2.4.1
用户可以通过Power BI中的“快度量值”功能,以无代码的方式快速创建度量,提高工作效率。对于特别复杂的度量,仍然需要手工创建。
单击图2.4.18中的“快度量值”命令,在打开的对话框中将“计算”设为“年增率变化”,“基值”设为度量Sales,“日期”设为Date,“期间数”设为1,代表计算1个单位的年同比值,单击“确定”按钮完成,如图2.4.19所示。
图2.4.18
图2.4.19
在字段栏中找到前面创建的同比值,在公式栏中观察其对应的代码,如图2.4.20所示。代码的核心是CALCULATE函数。该函数的作用是进行筛选上下文(Filter Context)的转换,其中筛选部分使用了DATEADD函数筛选去年同比值。VAR…RETURN函数中的VAR参数用于存储变量,RETURN参数用于输出变量计算结果。这种写法易于阅读和理解。
图2.4.20
参照前面的步骤,再次打开“快度量值”对话框,将“计算”设为“移动平均”,然后参照图2.4.21配置参数,此处为计算12个月的月度销售平均值。
图2.4.21
图2.4.22为快度量值自动产生的代码,其中的重点部分为:
DATESBETWEEN:选取时间范围,此处选取当前时间前后6个月的数据。
AVERAGEX(CALCULATETABLE(SUMMARIZE(VALUES())),CALCULATE()):这部分稍微复杂,使用了多重嵌套函数。因为DAX的计算方向是从内向外的,因此这里也依据该顺序介绍DAX函数。
VALUES():返回字段中唯一值的表。
SUMMARIZE():摘要表函数,依据提供的表进行分组,此处根据日期表,得出月份字段。
CALCULATETABLE():与CALCULATE函数相似,但返回对象为表。此处用于返回12个月的日期表。
AVERAGEX():平均迭代函数,依据提供的表格与表达式,返回表达式平均值。此处CALCULATETABLE函数的返回值为表格输入值、CALCULATE为表达式。
图2.4.22
有趣的是,快度量除可以创建数值度量外,还可以创建非数值度量,如销售额的星级评分,如图2.4.23所示。该度量用于制订销售的评分标准,用户可以设置评分的星数、评分值范围。
图2.4.23
图2.4.24显示了系统自动产生的代码,其中的重点部分为:
DIVIDE():分子为当前销售额值与销售额最小值之差,分母为销售额最大值与销售额最小值之差,结果为分子与分母的比率。
ROUND():将比率乘以星星个数,再进行取整。
UNICHAR():显示UNICODE字符的值,9733代表星星个数。
REPT():按提供的数值重复字符。
图2.4.:24
前文创建了数个度量,但度量被散落在不同的表中,如图2.4.25所示,这种情况不利于度量的管理与使用。实际上,Power BI中的度量不依存于任何报表。更合理的方式是将度量统一集中存放管理,具体操作如下所示。
图2.4.25
单击“输入数据”命令,如图2.4.26所示。
图2.4.26
在弹出的对话框中(见图2.4.27),更改名称为“度量值”,单击“加载”按钮。
图2.4.27
选中Profit度量,在主表中选择“度量值”命令。度量被移动到新的表中,如图2.4.28所示。
图2.4.28
重复以上操作,直至所有的度量被统一放置在同一个文件夹下。再将“列1”列删除,如图2.4.29所示。
图2.4.29
参照图2.4.30所示的步骤将字段栏打开,发现度量值文件夹的图标发生了变化,因为这里面只存放度量。
图2.4.30
在度量值文件夹中提供了统一的存放路径,对于复杂的模型,可能有成百上千的度量。我们可以进一步创建子文件夹。在模型视图下,选中“Profit”度量,在属性栏中的“显示文件夹”中输入“利润度量”,见图2.4.31左图。用户可在按Shift键的同时选择多个度量,然后一次性命名子文件夹,见图2.4.31右图。
图2.4.31
最后介绍一下度量的命名规则。好的命名有助于用户理解度量,通过层级命名是一个不错的选择。例如将Profit%命名为Profit.Rate;将Profit命名为Profit.Sum,见图2.4.32。
图2.4.32
用户还可以为度量添加额外的说明,使其他人在浏览度量时,可以方便地查询度量的详细说明,见图2.4.33。
图2.4.33
为了分析客户的销售贡献,需要将客户的年龄进行分组。在数据视图下,在DimCustomer表下选中“Age”字段,单击“列工具→组→数据组”命令,见图2.4.34。
图2.4.34
在弹出的对话框中,可见字段的最小值和最大值分别为20和60,组类型为“箱”。参照图2.4.35,对组进行命名,将装箱大小调整为“10”,单击“确定”按钮。
图2.4.35
图2.4.36为新建的客户年龄组,如30、40、50。字段旁有装箱图标。
图2.4.36
用户可根据装箱大小创建不同的年龄组,也可以自行删除,如图2.4.37所示。
图2.4.37
根据在业务理解阶段的需求分析,需要创建销售可视化地理表。为此,在数据建模阶段,需要先设置地理属性与层级。
在数据视图下,在地理表中选中CountryRegionName字段,单击菜单中的“列工具→数据类别”命令,在打开的下拉菜单中选择“国家/地区”命令,见图2.4.38。依次选中City Name字段与StateProvinceName字段,并参照该方法选择对应的数据类别。
注意: 修改后的字段旁出现了地球标示,意味该字段具有地理属性。Power BI中内置的地图搜索引擎是Bing。字段类型定义得越准确,Bing越能准确地定位,如图2.4.39所示。
图2.4.38
图2.4.39
在数据分析中,各种数据经常会存在依存关系。参照图2.4.40,右击CountryRegion Name字段,在弹出的下拉菜单中选择“新的层次结构”命令。依次右击其余字段,在弹出的下拉菜单选择“添加到层级结构”命令中对应的层级,完成层级结构的创建。双击层级结构名称,可为字段重命名。
图2.4.40
可参照地理层级,创建产品层级,如图2.4.41所示。
图2.4.41