业务中,常常需要显示 TOP N 的排名前几的产品(或门店,区域)和销售额(或其他指标)。尴尬的问题在于,如果指标的大小一样,会出现重复的元素的情况。例如:

如果只想显示前三,应该是:K,F,G。其中,F 和 G 是 30 个 60 中的任意两个即可。而不再显示后续元素,要实现的效果如下:

这该怎么做呢?
数据模型上,没有什么特别的,这里用一个简单的模型来举例子。如下:

基础度量值,如下:
KPI := SUM(sales[销售额])
Calendar.YearMonth := SELECTEDVALUE( 'Calendar'[年度月份] )
基于基础度量值,来定义 TOP 的方法,如下:
TOP1.Text =
// 设定需要的 TOP X 元素,例如排名第一的元素
VAR xTopXOrder = 1
// 以下内容无需改变
// 1.从数据中捞取需要的内容
VAR tView =
CALCULATETABLE(
ADDCOLUMNS(
SUMMARIZE( 'sales', sales[类别] ) ,
"@KPI",[KPI]
) ,
ALLSELECTED()
)
// 2.按照KPI和Item名称做两种初步排序
VAR tViewRank =
ADDCOLUMNS( tView ,
"@RankByKPI" , RANKX( tView , [@KPI] ) ,
"@RankByItem" , RANKX( tView , [类别] )
)
// 3.按照初步排序做一个总排序,主排序按照KPI来,当KPI值相同的时候再按名称排序
VAR tViewRankRank =
ADDCOLUMNS( tViewRank ,
"@RankTotalValue" , [@RankByKPI] + [@RankByItem] / 100 ,
"@RankTotalOrder" , RANKX( tViewRank , [@RankByKPI] + [@RankByItem] / 100 , [@RankByKPI] + [@RankByItem] / 100 , ASC )
)
// 4.找出与当前TOP相匹配的记录
VAR rItem = FILTER( tViewRankRank , [@RankTotalOrder] = xTopXOrder )
RETURN
CONCATENATEX(
rItem ,
[类别] & ":" & [@KPI]
)算法的解释已经在以上公式中描述了,这里就不再另外解释。
这里用到了很多重要的约定,设计模式,技巧。分别说明一下。
在数据模型中,会遇到四种情况:
很多初学者问如何化简学习难度,好的习惯和约定就是一种重要的方法。
约定不是必须的,有人喜欢把变量的名字起名为:
VAR a = ...
VAR b = ...
VAR xiaoShouJinE = ...可以是可以,但并不优雅。为啥要优雅?因为,优雅就在那里。
在计算中,其通用套路就是一种设计模式,描述为:
步骤一,从高度压缩的数据模型中取数,套路为:
VAR tView =
CALCULATETABLE(
ADDCOLUMNS(
SUMMARIZE( 'sales', sales[类别] ) ,
"@KPI",[KPI]
) ,
ALLSELECTED()
)步骤二,针对步骤一获得的数,进一步做运算,套路为:
基于步骤一的结果,临时固化,此结果不再改变,也就意味着,不再收到筛选上下文或上下文转换的影响,极大降低了使用难度。
通过运算得到最终结果。
这里使用的技巧包括:
PowerBI 中学习 DAX 是有很好的模式可以遵循的,可以大幅度缩小学习曲线,也可以让业务人员真正把 DAX 和 Power BI 作为工具,而不用具体钻研它。这些在《BI 真经》中都有系统讲解,这里就不再重复了。
当然,如何将整个套路更加简化,的确有更直接的感悟,会在另外的文章中分享。