【问题标题】:How to calculate rank within Sales ranges如何计算销售范围内的排名
【发布时间】:2019-12-03 10:40:58
【问题描述】:

如何计算按销售级别定义的类别中的排名。假设我们希望将销售额高于某个阈值的产品标记为“高”类别,低于该阈值的产品标记为“低”类别。

这是一个示例数据。

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 表然后尝试引用它,我的试验也失败了。

以下是预期结果:

参考文献

这是我在接近陈述这个问题的过程中遇到的一系列相关问题。

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

【问题讨论】:

  • 你能展示你想要的结果吗?
  • @AlexisOlson 预期结果已送达!

标签: powerbi dax


【解决方案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 )
    )

输出:


编辑:

要处理一个类别中只有 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 )
        )
    )

【讨论】:

  • 到目前为止我还没有考虑过。如果 CalculatedCategory 只有一种产品怎么办?然后Exp。结果为空白。绝对不应该。如果它是 0% 或 100%,但绝对不是空白的 Excel 等效函数显示一个单元格数组的 100%,我会很满意。我在 0% 或 100% 之间的唯一偏好是代码的可读性。越简单越好。
  • Alexis,很高兴给你赏金。我对 RANKX 没有运气。我不断收到不同销售额的排名关系。我将尝试制作一个复制该行为的示例。我分享了一个解决该问题的解决方案。没有您的回答,我将无法实现。谢谢。
【解决方案2】:

非常感谢 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 来计算类别内的百分比排名。我使用了 COUNTROWS 和过滤器的混合物。

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 返回类别中的产品数量。

【讨论】:

    猜你喜欢
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多