白茶在之前的文章中,给大家介绍过Rank函数的应用场景,其实与Rank函数同时推出的还有RowNumber函数,二者之间有一些差异,但是总体应用的场景基本类似。
RowNumber函数基本语法
ROWNUMBER ( [<relation>][, <orderBy>][, <blanks>][, <partitionBy>][, <matchBy>] )
参数介绍:
relation:可选项,排名依据的表或表表达式。
orderBy:可选项,排序依据,如果省略,第2参数需绑定。
blanks:可选项,处理空值排名位置使用。
partitionBy:可选项,分区定义,参照SQL的开窗分区即可。
matchby:可选项,定义匹配数据和标识当前行的列的语句。
PS:
从内部参数上我们不难发现,对比Rank函数,RowNumber就是缺少了一个ties参数。
其实,如果小伙伴们擅长SQL的话,就会明白,这两个开窗函数就是从SQL移植过来的,只不过语法上存在差异,而实际用途基本一致。
先来看看本期的案例数据:
案例数据共计3张表,产品表、分店表以及事实表,将其导入到PowerBI中,模型关系如下:
添加基础度量值:
销售金额:
001.SalesAmount =
SUMX ( 'Fact_Sales', 'Fact_Sales'[Quantity] * RELATED ( Dim_Product[Price] ) )
销售成本:
002.SalesCost =
SUMX ( 'Fact_Sales', 'Fact_Sales'[Quantity] * RELATED ( Dim_Product[Cost] ) )
销售利润:
003.SalesProfit =
[001.SalesAmount] - [002.SalesCost]
销售单价:
001.Price =
SUM ( 'Dim_Product'[Price] )
销售单位成本:
002.Cost =
SUM ( 'Dim_Product'[Cost] )
到这里,我们的准备工作完成,我们来看看RowNumber函数的表现。
①.浮点运算
与Rank函数类似,我们来看一下RowNumber在处理排名时,是否会存在浮点运算问题,添加如下度量值:
004.ProfitRankx =
IF (
HASONEFILTER ( Dim_Store[City] ),
RANKX ( ALLSELECTED ( 'Dim_Store' ), [003.SalesProfit] )
)
其结果如下图:
添加RowNumber计算逻辑:
006.ProfitRowNumber =
ROWNUMBER ( ALLSELECTED ( 'Dim_Store' ), ORDERBY ( [003.SalesProfit], DESC ) )
结果如下:
与Rank函数一致,RowNumber函数内部也是可以自动解决浮点运算的问题。
②.并列排名
我们来看一下RowNumber在并列排名中的表现,添加如下度量值:
Rank排名:
003.RankPrice =
RANK ( ALLSELECTED ( 'Dim_Product' ), ORDERBY ( [001.Price], ASC ) )
RowNumber排名:
004.RowNumberPrice =
ROWNUMBER ( ALLSELECTED ( 'Dim_Product' ), ORDERBY ( [001.Price], ASC ) )
结果如下:
我们继续添加如下度量值:
Rank并列排名:
005.RankPriceCost =
RANK (
ALLSELECTED ( 'Dim_Product' ),
ORDERBY ( [001.Price], ASC, [002.Cost], ASC )
)
RowNumber并列排名:
006.RowNumberPriceCost =
ROWNUMBER (
ALLSELECTED ( 'Dim_Product' ),
ORDERBY ( [001.Price], ASC, [002.Cost], ASC )
)
结果如下:
解释描述:
1.从结果上看,当OrderBy参数只有一个时,Rank会出现并列排名,而RowNumber则不会,会按照顺序依次打标签序号,这点其实和SQL中二者的区别是一致的;
2.当OrderBy参数不唯一时,二者结果一致;
3.这里补充一下,Rank函数的第一参数ties如果省略,则默认为SKIP,排序结果为:1、2、2、4,如果设置为DENSE,则排序结果为:1、2、2、3;
4.性能问题的话,感兴趣的小伙伴可以自行动手测试,白茶这里就不赘述了。