如何计算销售范围内的排名

时间:2019-12-03 10:40:58

标签: powerbi dax

如何在销售级别定义的类别内计算排名。假设我们要为“销售额”标记产品的某个阈值高于“高”类别,而低于该阈值的商品“低”类别。

这是示例数据。

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WcisqzSwpVtJRSiwoyEkF0oZKsTpIwkmJeUAIZJigipfn56QlpRYVVQLZpqhSyRlQcWOweFhqempJYlJOKlgusagovwS7XEF+SWJJPtwJKHL5eZn5eUDaHNUqHI5GdkEsAA==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type text) meta [Serialized.Text = true]) in type table [Category = _t, Product = _t, Amount = _t]),
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Amount", Int64.Type}})
in
    #"Changed Type"

我的问题是与its older uncle有关的侄子,现在我想打电话给他:

Percent Rank within Category = 

VAR HasOneValueTrue = HASONEVALUE ( MyTable[Product] )

VAR tbl =
    CALCULATETABLE (
        VALUES ( MyTable[Product] ),          
        REMOVEFILTERS ( MyTable[Product] ),   
        VALUES ( MyTable[Category] )          
    )

VAR result =
    CALCULATE (
        DIVIDE (
            RANKX (
                tbl,
                [Sales], 
                ,
                ASC
            ) - 1,
            COUNTROWS ( tbl ) - 1
        )
    )
RETURN 
    IF (
        HasOneValueTrue,
        result
    )

区别在于,叔叔在表列中定义了类别,但是现在我们希望根据销售水平即时计算类别。所以我尝试了 将VAR tbl代码替换为阈值4的以下代码:

var tbl =
SUMMARIZECOLUMNS (
    MyTable[Product],
    "CalculatedCategory", IF ( [Sales] > 4, "high", "low" ),
    "AggSales", [Sales]
)

尽管如此,我无法引用这样的定义变量。基于首先创建DAX表然后尝试引用它的尝试,我也失败了。

以下是预期结果:

expected results

参考

以下是我在陈述该问题时碰到的一系列相关问题。

DAX equivalent of Excel PERCENTRANK.INC per category

DAX RANKX for within Category

DAX REMOVEFILTERS vs ALL

The value parameter in DAX function RANKX

DAX ALLEXCEPT to sum by category of multiple dimension tables

2 个答案:

答案 0 :(得分:1)

只需对我的answer here进行较小的修改即可完成此操作。复制如下:

Percent Rank =
VAR ProductsInCategory =
    CALCULATETABLE (
        VALUES ( MyTable[Product] ),
        ALLSELECTED ( MyTable[Product] )
    )
VAR RankProduct = RANKX ( ProductsInCategory, [Sales],, ASC )
RETURN
    IF (
        HASONEVALUE ( MyTable[Product] ),
        DIVIDE ( RankProduct - 1, COUNTROWS ( ProductsInCategory ) - 1 )
    )

首先,根据您的建议定义计算的类别。

CalculatedCategory = IF ( [Sales] > 4, "high", "low" )

然后将其插入ProductsInCategory变量的过滤器中。

Exp. Results =
VAR CalculatedCategory = [CalculatedCategory] /*Determine current category*/
VAR ProductsInCategory =
    CALCULATETABLE (
        VALUES ( MyTable[Product] ),
        FILTER (
            ALLSELECTED ( MyTable[Product] ),
            [CalculatedCategory] = CalculatedCategory /*New Condition*/
        )
    )
VAR RankProduct = RANKX ( ProductsInCategory, [Sales],, ASC )
RETURN
    IF (
        HASONEVALUE ( MyTable[Product] ),
        DIVIDE ( RankProduct - 1, COUNTROWS ( ProductsInCategory ) - 1 )
    )

输出:

Matrix Visual


编辑:

要处理类别中只有1个产品的情况,可以使用MAX来禁止分母为零。

Exp. Results =
VAR CalculatedCategory = [CalculatedCategory] /*Determine current category*/
VAR ProductsInCategory =
    CALCULATETABLE (
        VALUES ( MyTable[Product] ),
        FILTER (
            ALLSELECTED ( MyTable[Product] ),
            [CalculatedCategory] = CalculatedCategory /*New Condition*/
        )
    )
VAR RankProduct = RANKX ( ProductsInCategory, [Sales],, ASC )
RETURN
    IF (
        HASONEVALUE ( MyTable[Product] ),
        DIVIDE (
            RankProduct - 1,
            MAX ( COUNTROWS( ProductsInCategory ) - 1, 1 )
        )
    )

答案 1 :(得分:0)

非常感谢Alexis Olson,我想分享一下最终得到的另一种解决方案。 Alexis提出的解决方案在我的简单示例中效果很好,但在我的复杂模型中却没有效果。在我的复杂模型中,RANKX函数无法提供预期的结果。 RANKX针对不同的销售价值返回相同的排名。

目前,此解决方案有效,无需弄清楚是什么原因导致RANKX返回具有不同销售价值的关系。

首先,定义类别度量:

CalculatedCategory = 
SWITCH (
    TRUE (),
    NOT ( HASONEVALUE ( MyTable[Product] ) ), "total", -- important to handle totals
    [Sales] <= 4, "low",
    [Sales] >  4, "high",
    "other"
)

从类别中排除总计很重要。我通过设置总计的其他类别来做到这一点。否则,总数将属于“高”类别类别。这会扭曲最终结果。

我没有在类别中的百分比排名计算中使用RANKX。我使用了MIXTURE OF COUNTROWS和FILTER。

PercentRank within Category = 
VAR category = [CalculatedCategory]
VAR ProductSales = [Sales]
VAR ProductsMatching = 
COUNTROWS (
            FILTER (
                ALLSELECTED ( MyTable[Product] ),
                [CalculatedCategory] = category
                    && [Sales] >= ProductSales
            )
        )
var ProductsAll = 
COUNTROWS (
            FILTER (
                ALLSELECTED ( MyTable[Product] ),
                [CalculatedCategory] = category
            )
        )

RETURN
    DIVIDE (ProductsMatching-1, MAX( ProductsAll-1, 1 ))

我计算了两个表的行。第一个表ProductsMatching包含所有具有适当类别销售额和高于或等于该产品销售额的产品。 ProductsAll返回类别中的产品数。