【问题标题】:Excluding rows and create rank排除行并创建排名
【发布时间】:2026-02-11 19:15:01
【问题描述】:

我正在尝试创建一个仅对具有特定值的行进行排名的排名。我创建了一个名为“RankingTop”的列,按 ReportType 和 ReportDate 进行排名。所以有2个独立的排名。我正在尝试仅为具有 isCurrent =“no”的行创建排名。这是我现在拥有的代码和数据集以及我想要实现的目标。请让我知道这是否可能。或者我可以在 PowerQuery 中执行此操作。

RankingTop = RANKX (
FILTER(
    Table,
    Table[ReportType]
        = EARLIER(Table[ReportType])
)
, Table[ReportDate]
,
, DESC
)

当前数据集

| ReportType | ReportDate | RankingTop | MonthYear | isCurrent |
|------------|------------|------------|-----------|-----------|
| Weekly     | 12/27/2021 | 1          | Dec-21    | no        |
| Weekly     | 12/20/2021 | 2          | Dec-21    | no        |
| Weekly     | 12/13/2021 | 3          | Dec-21    | no        |
| Weekly     | 12/6/2021  | 4          | Dec-21    | no        |
| Weekly     | 11/29/2021 | 5          | Nov-21    | no        |
| Weekly     | 11/22/2021 | 6          | Nov-21    | no        |
| Weekly     | 11/15/2021 | 7          | Nov-21    | no        |
| Weekly     | 11/8/2021  | 8          | Nov-21    | no        |
| Weekly     | 11/1/2021  | 9          | Nov-21    | no        |
| Monthly    | 7/1/2021   | 7          | Jul-21    | no        |
| Monthly    | 8/1/2021   | 6          | Aug-21    | no        |
| Monthly    | 9/1/2021   | 5          | Sep-21    | no        |
| Monthly    | 10/1/2021  | 4          | Oct-21    | no        |
| Monthly    | 11/1/2021  | 3          | Nov-21    | no        |
| Monthly    | 12/1/2021  | 2          | Dec-21    | no        |
| Monthly    | 1/1/2022   | 1          | Jan-22    | yes       |

我想要达到的目标

| ReportType | ReportDate | RankingTop | MonthYear | isCurrent |
|------------|------------|------------|-----------|-----------|
| Weekly     | 12/27/2021 | 1          | Dec-21    | no        |
| Weekly     | 12/20/2021 | 2          | Dec-21    | no        |
| Weekly     | 12/13/2021 | 3          | Dec-21    | no        |
| Weekly     | 12/6/2021  | 4          | Dec-21    | no        |
| Weekly     | 11/29/2021 | 5          | Nov-21    | no        |
| Weekly     | 11/22/2021 | 6          | Nov-21    | no        |
| Weekly     | 11/15/2021 | 7          | Nov-21    | no        |
| Weekly     | 11/8/2021  | 8          | Nov-21    | no        |
| Weekly     | 11/1/2021  | 9          | Nov-21    | no        |
| Monthly    | 7/1/2021   | 6          | Jul-21    | no        |
| Monthly    | 8/1/2021   | 5          | Aug-21    | no        |
| Monthly    | 9/1/2021   | 4          | Sep-21    | no        |
| Monthly    | 10/1/2021  | 3          | Oct-21    | no        |
| Monthly    | 11/1/2021  | 2          | Nov-21    | no        |
| Monthly    | 12/1/2021  | 1          | Dec-21    | no        |
| Monthly    | 1/1/2022   |            | Jan-22    | yes       |

【问题讨论】:

  • 您当然可以在 Power Query 中轻松做到这一点,但它似乎比 DAX 公式更复杂。如果您更喜欢 PQ,请告诉我,我会发布一些内容。
  • @RonRosenfeld 如果可能的话,我更喜欢 PQ 中的任何内容。请告诉我!谢谢!

标签: powerbi dax powerquery


【解决方案1】:

您可以调整您的计算列以返回 BLANK if isCurrent = "yes",并过滤 isCurrentReportType

RankingTop = 
    IF ( 
        'Table'[isCurrent] = "yes",
        BLANK(),
        RANKX (
            FILTER(
                'Table',
                'Table'[ReportType] = EARLIER ( 'Table'[ReportType] ) && 
                'Table'[isCurrent] <> "yes"
            ), 
            'Table'[ReportDate],
            ,
            DESC
        )
    )

【讨论】:

    【解决方案2】:

    在 Power Query 中,创建“排名”的一种方法是对列表进行排序,然后添加索引列。

    如果我正确理解您的问题,我们需要:

    • 按报告类型分组
    • 对于每个组(我为此使用了自定义函数,但您可以将其包含在主代码中)
      • 按日期降序对表格进行排序
      • 向该子表添加索引列
      • 使用过滤表为排序/添加索引列创建第二个表
    • 然后使用日期作为键加入排名表
    • 终于重新排序回到原来的顺序
    • 我还添加了月/年列,并按照您在所需输出表中显示的顺序排列了顺序

    请阅读 M-Code 中的 cmets 了解更多详情 在这种情况下,我只从三列开始:ReportTypeReportDateisCurrent

    原始数据

    自定义函数
    将代码粘贴到 BlankQuery 中并将其重命名为 fnRank

    (t as table, col as text)=>
    let 
        sortedTable = Table.Sort(t,{col, Order.Descending}),
        addRank = Table.AddIndexColumn(sortedTable,"Rank",1,1,Int64.Type)
    in addRank
    

    M 码

    let
        Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
        #"Changed Type" = Table.TransformColumnTypes(Source,{
            {"ReportType", type text}, 
            {"ReportDate", type date}, 
            {"isCurrent", type text}
                }),
    
    //add index to preserve original date order
        #"Added Index" = Table.AddIndexColumn(#"Changed Type", "Index", 0, 1, Int64.Type),
    
    //group by ReportType, sort and add index column for the ranking
        #"Grouped Rows" = Table.Group(#"Added Index", {"ReportType"}, {
            {"rank", each fnRank(_,"ReportDate"), type table},
    
    //filter with parameter isCurrent=No
            {"rank2", each fnRank(Table.SelectRows(_,each [isCurrent]="no"), "ReportDate"), type table}
            }),
    
    //join the two tables with the regular and filtered rank
        #"Added Custom" = Table.AddColumn(#"Grouped Rows", "joinRanks", 
            each Table.NestedJoin([rank],"ReportDate",[rank2],"ReportDate","ranks",JoinKind.LeftOuter)),
    
    //remove unneeded columns and expand the join
        #"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"rank", "rank2"}),
        #"Expanded joinRanks" = Table.ExpandTableColumn(#"Removed Columns", "joinRanks", 
            {"ReportDate", "isCurrent", "Index", "Rank", "ranks"}, {"ReportDate", "isCurrent", "Index", "RankingTop", "ranks"}),
        #"Changed Type1" = Table.TransformColumnTypes(#"Expanded joinRanks",{
            {"ReportDate", type date}, {"isCurrent", type text}, {"Index", Int64.Type}, {"RankingTop", Int64.Type}}),
    
    //add a column to extract the filtered rank
    //then remove the table column
        #"Added Custom1" = Table.AddColumn(#"Changed Type1", "RankingTopNo", 
            each try Table.SelectColumns([ranks],"Rank")[Rank]{0} otherwise null, Int64.Type),
        #"Removed Columns1" = Table.RemoveColumns(#"Added Custom1",{"ranks"}),
    
    //Sort back to the original order using Index column
    //then remove the Index Column
        #"Sorted Rows" = Table.Sort(#"Removed Columns1",{{"Index", Order.Ascending}}),
        #"Removed Columns2" = Table.RemoveColumns(#"Sorted Rows",{"Index"}),
    
    //add MonthYear column as text
        #"Added Custom2" = Table.AddColumn(#"Removed Columns2", "MonthYear", 
            each Date.ToText([ReportDate],"MMM-yy"), type text),
        #"Reordered Columns" = Table.ReorderColumns(#"Added Custom2",{"ReportType", "ReportDate", "RankingTop", "RankingTopNo", "MonthYear", "isCurrent"})
    in
        #"Reordered Columns"
    

    结果>

    【讨论】:

      【解决方案3】:

      另一个 Power Query 选项:

      let
          Source = Table.TransformColumnTypes(Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("fdDBCoAgEATQf9mzoLtR6kd07iAehaDQQ138+6xugnPb4TEwbAi0pXSclRSxaLFajHALuVBUHRqAPAFchsZaPEIByDNAh4qdrSXf+4cWmAPmgbFBiNa8bx3jb9LOmi6K8QE=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [ReportType = _t, ReportDate = _t, isCurrent = _t]),{{"ReportDate", type date}}, "en-US"),
          #"Added Sort" = Table.AddIndexColumn(Source, "Original Sort", 1, 1, Int64.Type),
          #"Created Partitions" = Table.Group(#"Added Sort", {"ReportType", "isCurrent"}, {{"Data", each _, type table}}),
          fnRank = (MyTable as table) =>
          let
              #"Sorted Rows" = Table.Sort(MyTable,{{"ReportDate", Order.Descending}}),
              #"Added Index" = if #"Sorted Rows"[isCurrent]{0} = "no" then Table.AddIndexColumn(#"Sorted Rows", "Rank", 1, 1, Int64.Type) else #"Sorted Rows"
          in
              #"Added Index",
          #"Augmented Partitions" = Table.AddColumn(#"Created Partitions", "RankedData", each fnRank([Data]), type table),
          #"Combined Partitions" = Table.Combine(#"Augmented Partitions"[RankedData]),
          #"Sorted Rows" = Table.Sort(#"Combined Partitions",{{"Original Sort", Order.Ascending}}),
          #"Removed Columns" = Table.RemoveColumns(#"Sorted Rows",{"Original Sort"})
      in
          #"Removed Columns"
      

      输入:

      输出:

      【讨论】: