Power Query - 具有性能问题的 COUNTIFS 模仿者。哪种方法更好?

Power Query - COUNTIFS copycat with performance issue. Which is a better approach?

场景和数据结构很简单

我有一个清单,其中包含产品代码和该产品的零售月份。可以在下图中的前两列绿色部分看到此类数据的示例。

然后我需要检查每个产品是否也在上个月、过去 3 个月或过去 12 个月内零售过。结果将是图像上接下来的三列黄色。

这些计算(黄色列)很容易在 Excel 处使用一些 IF 和 COUNTIFS 公式计算,但是当将其迁移到 Power BI 时,我在 Power Query 中遇到代码性能问题.由于每个月有数千种产品,Power Query 计算时间过长。

检查下面我设计的代码。代码快照将用于第二个黄色列,以告知该产品在过去 3 个月是否有零售。

本质上,我正在做的是添加一个计算列,该列计算 table 的行数,该列使用产品代码信息和相关日期进行过滤。

在性能方面获取所需信息的更好方法是什么?

谢谢。

代码:

// Add a calculated column.
AdicionarHits03Meses = Table.AddColumn(
    AdicionarHits01Mes,
    "Hit nos últimos 3 meses?",
    (r)=> 
        
        // Check if...
        if    
        
            // Returns the rows count of a table.
            Table.RowCount(
                
                // Returns a table with the condition.
                Table.SelectRows(
                    ChangeType,

                    // Condition:
                    (q)=> 

                        // Same Product Code.
                        q[#"Product Code"] = r[#"Product Code"] 
                        
                        and 
                        
                        // Check the retail month.
                        q[#"Retail month"] <= Date.AddMonths(r[#"Retail month"], -1) and
                        q[#"Retail month"] >= Date.AddMonths(r[#"Retail month"], -3)
                )
            )

        = 0 then
        
        // No retail found.
        0 else

        // Retail found.
        1
    
    ,
    Int64.Type
)

您可以通过一些巧妙的自合并来提高性能。

看看这对你是否有意义:

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMlTSUfJKzFMwMjAyVIrViVYyQhcwRhcAaXFLTUIV8E0sQjXDN7ESzdDSHKhALAA=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [#"Product Code" = _t, #"Retail Month" = _t]),
    Original = Table.TransformColumnTypes(Source,{{"Product Code", Int64.Type}, {"Retail Month", type date}}),
    #"Added Offset Lists" = Table.AddColumn(Original, "Offset", each {1..12}),
    #"Expanded Offset Column" = Table.ExpandListColumn(#"Added Offset Lists", "Offset"),
    #"Added Prev Column" = Table.AddColumn(#"Expanded Offset Column", "Prev", each Date.AddMonths([Retail Month], -[Offset] ), type date),
    #"Inner Join Prev to Original" = Table.NestedJoin(#"Added Prev Column", {"Product Code", "Prev"}, Original, {"Product Code", "Retail Month"}, "Retail", JoinKind.Inner),
    #"Merge Original to Prev" = Table.NestedJoin(Original, {"Product Code", "Retail Month"}, #"Inner Join Prev to Original", {"Product Code", "Retail Month"}, "Min Offset", JoinKind.LeftOuter),
    #"Expanded Min Offset" = Table.TransformColumns(#"Merge Original to Prev", {{"Min Offset", each List.Min([Offset]), Int64.Type}}),
    #"Added Last Month" = Table.AddColumn(#"Expanded Min Offset", "Retail last month", each if [Min Offset] = 1 then "Yes" else "No", type text),
    #"Added Last 3 Months" = Table.AddColumn(#"Added Last Month", "Retailed since last 3 months", each if [Min Offset] <> null and [Min Offset] <= 3 then "Yes" else "No", type text),
    #"Added Last 12 Months" = Table.AddColumn(#"Added Last 3 Months", "Retailed since 12 months", each if [Min Offset] <> null and [Min Offset] <= 12 then "Yes" else "No", type text)
in
    #"Added Last 12 Months"

我没有时间详细解释但大纲大致如下:

  1. 将每行扩展到前几个月的 12 行。
  2. 将之前的月份与原始 table 中的行相匹配。
  3. 将原始行与为该行找到的所有匹配项合并。
  4. 为每个匹配集找到最近的匹配(最小偏移)。
  5. 使用此偏移量定义 1、3 和 12 个月的回顾列。