本文翻译自Nikola Ilic的文章—《Static vs Dynamic ranking in Power BI》来源:Medium 学习如何以多种不同的方式处理最常见的业务请求之一!
我最畅销的产品是什么?哪些客户在我的服务上花的钱最多?哪些商店卖出了我们的奢侈品牌的最多单位?回答这些以及很多类似的问题是创建Power BI报告时最常见的要求之一。
为了能够根据上述问题的答案做出正确的商业决策,我们需要确定各自的价值并对其进行相应的排序。
DAX为处理排序问题提供了两个不同的函数--RANKX和TOPN。正如你可以直观地得出的结论,TOPN功能可以帮助你识别例如最畅销产品TOP5,或去年购买最多的前10个客户。然而,TOPN不在本文的讨论范围内,因为我们将重点讨论RANKX函数...
了解静态排名
静态排名将一个排名分配给一个特定的值,并且这个排名不会改变——不管你是否筛选结果!让我们在一个实际的例子中看看效果如何,使用示例Contoso数据库。
首先,让我们在FactOnlineSales表中创建一个明确的度量来计算销售金额。
SalesAmt = SUM(FactOnlineSales[SalesAmount])
现在,为了查看哪些产品给我们带来了最多的收入,我们需要在DimProduct表中创建一个新的列。这一列将被用来根据销售金额为特定产品分配一个排名。
Rank Product Sales Amt = RANKX( DimProduct, [Sales Amt] )
正如你所注意到的,Power BI为我们的行分配了排名,排名取决于销售金额的值。
让我们利用这一计算,检查哪些产品的销售金额最大。
咦?1、2、4、5号呢......?到底发生了什么?回到文章的开头,我明确说过:排名不会改变--无论你对结果进行筛选或不进行筛选,排名都不会改变!这就是我的观点。所以,‘长焦转换镜头’将永远是第3名(除非基础数据发生变化),无论是否应用了筛选!
因此,让我们调整我们的计算,在特定的品牌内设置一个适当的计算。
RankProduct Brand = RANKX( ALLEXCEPT(DimProduct,DimProduct[BrandName]),[Sales Amt] )
在这里,ALLEXCEPT函数将删除DimProduct表中的筛选器,只保留BrandName列的筛选器,现在我们将得到不同的结果。
这样做很好,但这个解决方案远非完美。试想一下,为每一个切片器创建一个单独的计算列--这将是相当麻烦和乏味的工作。更不用说这将扩大你的数据模型,因为所有的计算列在每次数据刷新时都会被评估和物化,而且它们会消耗一定的内存。
了解动态排名
每当你听到Power BI中的动态一词时,你应该假定你将不得不处理度量,而不是列。也就是说,如果你想在你的Power BI报告中应用动态排名,这意味着排名的值将被实时计算,并根据当前的筛选器上下文分配。
因此,让我们创建我们的度量,它将完全执行我们需要的动态计算排名。
RankProduct Measure = IF(ISINSCOPE(DimProduct[ProductDescription]),IF(NOTISBLANK([Sales Amt]),RANKX(ALLSELECTED(DimProduct),[SalesAmt])))
现在,如果我们看一下我们的表格,你会看到,排名将根据用户与报告的互动来分配。
在这个简短的视频中,你可以看到我的度量将根据用户的选择进行动态调整:如果在切片器中没有选择任何值,它的行为将与我们的第一个计算列完全一样。另一方面,一旦我在切片器中选择了一个特定的品牌,该度量将显示与我们第二个计算列相同的结果。
最后,让我们看看如果我们在切片器中选择多个品牌会发生什么。
由于我同时选择了Contoso和Litware,我们的度量将在当前的筛选器上下文中进行评估,并根据它来分配排名--Contoso和Litware现在代表了我们所应用的度量的子集。
总结
处理与排名有关的请求在大多数业务场景中都很常见,为了应用适当的计算,了解静态和动态排名之间的区别是绝对必要的。
对于这个要求,没有一个单一的正确的解决方案--你应该与你的用户交谈,检查他们所设想的分配排名的标准是什么。在任何情况下,如果可能的话,你应该倾向于应用动态排名,因为这不仅可以确保更多的灵活性,而且还可以减少你的数据模型的大小和维护工作带来的麻烦。
延伸阅读:
网友评论