Power BI DAX 窗口函数 ROWNUMBER

有伙伴问这样一个问题,说:如果给一个分组汇总表加一列行号,效果如下:

其特点在于,这里的 # 并不是排序,而是单纯的序号,甚至不要求它带有业务意义。

如何实现序号

这里故意举了一个复杂的例子,销售经理,产品类别,客户类型分别来自不同的表,因此,无法在它们三者的某一方做出发点,这三者具有一个共同的事实表:订单表。因此,要实现这里的效果可以写出这样的公式。

Table.RowNumber.By =

ROWNUMBER( CALCULATETABLE( SUMMARIZE( 'Fact 订单' , 'Dim 销售经理'[销售经理] , 'Dim 客户'[客户类型] , 'Dim 产品'[产品类别] ) , ALLSELECTED( ) ) )

注意,这里的 CALCULATETABLE ALLSELECTED 的用法是一种定式,表示在当前度量值中恢复这个透视表的分组汇总,记为 T。然后,ROWNUMBER 可以基于这个 T 进行默认的排序,并在这套排序中锁定当前筛选环境中唯一行的位置。

ROWNUMBER 虽然在语法上需要几个参数,但很多是可省略的,在这个例子中,只需要给出不同的维度组合的表即可。

ROWNUMBER 会在当前筛选上下文中锁定唯一的行,该行恰好与以上表的某唯一行所匹配,因此,会返回唯一值。

与 RANK 的区别

RANK 是在 ORDERBY 的基础上查找某项的排名,它与 ROWNUMBER 很相似,但一个例子就可以看出不同,如下:

可以看出,对于有着相同销售额的元素,排名是相同的,要么是紧凑排名,要么是稀松排名,而行序号仍然是唯一的。

这里的行序号的写法是:

Window.RowNumber =

ROWNUMBER( ALLSELECTED( 'DataTable'[Item] ) )

由于元素是 A,B,C,D,E,因此,可以观察到序号也是 A,B,C,D,E。

如果希望按照大小排列序号,当大小相同的时候,再按照名称来排列,可以用这样的写法:

Window.RowNumber =

ROWNUMBER( ALLSELECTED( 'DataTable'[Item] ) , ORDERBY( CALCULATE( SUM( 'DataTable'[Value] ) ) ) )

效果如下:

可以看出,在大小一样的情况下,会按元素的名字优先排序得到结果。

总结

对于窗口函数来说,其本质是形成一个窗口区域,ROWNUMBER 用于唯一化定位当前元素在窗口区域中的位置。这在实际中非常有用。

第一个应用便是一种设计模式:

如果要显示行号,那么,只需要按照本文案例即可得到行号。

第二个应用便是一种不会出现重复序号的排名,由于 ORDERBY 子句的存在,ROWNUMBER 所返回的结果必然是在某种排序状态下的,如果该排序已经可以满足唯一值,则返回该唯一值,若 ORDERBY 子句无法得到唯一值,则会继续使用其他列排序,例如本文案例。

灵活使用窗口函数,可以重新构造很多计算,大大加速计算性能。


(职场责编:李主编 )
2026年11月02日 12:02[查看原文]