【问题标题】:Countifs alternative in PowerQuery for MS PowerBIPower Query for MS Power BI 中的 Countifs 替代方案
【发布时间】:2022-12-11 12:35:16
【问题描述】:

我有一个有点复杂的 PowerQuery 查询,它有很多步骤。在这些步骤中,我有一个日期、团队和条件如下(不是实际数据)

所以挑战是我想计算每个团队每天的通过次数,然后为通过和失败创建另一个计数,然后它将用于我以后可以处理的大量计算。

我已经尝试了很多选项,例如分组,但它是如此令人困惑,因为正如我之前提到的,查询现在有太多的列和计算。我可以通过创建 DAX 度量成功地解决这个问题,但这里的问题是我需要计算平均结果,这是不可能的,因为我也无法对结果的度量进行平均。所以我别无选择,只能通过 PowerQuery 进行计数。

感谢您的帮助和想法。

作为文本的原始数据是here in google sheets

【问题讨论】:

  • 你能展示你的预期结果应该是什么样子吗?
  • 为什么不能在所需的分组内对度量进行平均?
  • @DavidBacci 我已经用结果表更新了谷歌表格,非常感谢
  • @Marcus 每次我尝试对度量进行平均时,它不会显示,只会显示表中的列。我用 VALUE 尝试了 AVERAGEX 但仍然没有运气:(
  • 您需要在最终结果中使用零值吗?

标签: powerbi powerquery powerbi-desktop


【解决方案1】:

我假设你的日期显示年份 0203 是一个错字,应该是 2023

不确定你到底想要什么输出,但你应该能够适应下面的内容。

该解决方案似乎是一个简单的分组,其中包含通过和/或失败的次数。

下面的代码为每个团队和日期的通过和失败生成一个单独的列。

它没有按照原来的顺序排序,但如果需要可以添加。

    #"Grouped Rows" = Table.Group(#"Previous Step", {"Date", "Team"}, {
        {"Pass", (t)=>List.Count(List.Select(t[#"PASS/FAIL"], each _ = "Pass")), Int64.Type},
        {"Fail", (t)=>List.Count(List.Select(t[#"PASS/FAIL"], each _ = "Fail")), Int64.Type}
    })

使用 Google 工作表中的数据表(更正年份后):

let
    Source = Excel.CurrentWorkbook(){[Name="Table12"]}[Content],
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Date", type date}, {"Team", type text}, {"PASS/FAIL", type text}}),
    #"Grouped Rows" = Table.Group(#"Changed Type", {"Date", "Team"}, {
        {"Pass", (t)=>List.Count(List.Select(t[#"PASS/FAIL"], each _ = "Pass")), Int64.Type},
        {"Fail", (t)=>List.Count(List.Select(t[#"PASS/FAIL"], each _ = "Fail")), Int64.Type}
    })
in
    #"Grouped Rows"

笔记如果您要求所有球队在所有日期都显示,即使他们没有参加比赛,也只需创建一个包含所有日期和球队的新表格;然后将其加入到原始表中,如下面的代码所示:

let
    Source = Excel.CurrentWorkbook(){[Name="Table12"]}[Content],
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Date", type date}, {"Team", type text}, {"PASS/FAIL", type text}}),

//If you need to show all teams on all dates, even if they didn't play on a date
//we merely create a blank table (dates and teams), and execute an outer join.
//then remove the original date/team columns before the grouping.
    #"Date List" = List.Distinct(#"Changed Type"[Date]),
    #"All Teams" =  List.Distinct(#"Changed Type"[Team]),
    Blank = Table.FromColumns(
                {List.Combine(List.Transform(#"Date List", each List.Repeat({_}, List.Count(#"All Teams")))),
                List.Repeat(#"All Teams", List.Count(#"Date List"))},
                type table[dates=date, teams=text]),
    join = Table.Join(Blank,{"dates","teams"}, #"Changed Type",{"Date","Team"}, JoinKind.LeftOuter),
    #"Removed Columns" = Table.RemoveColumns(join,{"Date", "Team"}),

    
    #"Grouped Rows" = Table.Group(#"Removed Columns", {"dates", "teams"}, {
        {"Pass", (t)=>List.Count(List.Select(t[#"PASS/FAIL"], each _ = "Pass")), Int64.Type},
        {"Fail", (t)=>List.Count(List.Select(t[#"PASS/FAIL"], each _ = "Fail")), Int64.Type}
    }),
    #"Sorted Rows" = Table.Sort(#"Grouped Rows",{{"dates", Order.Ascending}, {"teams", Order.Ascending}})
in
    #"Sorted Rows"

【讨论】:

  • 我喜欢这个解决方案,但是如何在 2/2/2023 上显示 AR 为零呢? OP 没有澄清是否确实需要这些,但确实在预期输出中显示了它们。
  • @DavidBacci 好点。希望他能澄清。但是如果有必要,对于没有在特定日期比赛的球队来说,添加这些行应该很容易。
  • 它看起来合乎逻辑,但出于某种奇怪的原因,它说找不到日期 :(Expression.Error: The column 'Date' of the table wasn't found. Details: Date
  • 对不起,我错误地将数据添加为 0203
  • @egflame 这就是它所说的意思。哪一步首先显示错误?该代码适用于您提供的数据。也许您的真实数据不同?不同的情况?列标题中的空间?
【解决方案2】:

如果您需要最终输出中的零,则需要进行交叉连接以引入原始文件中不存在的组合。

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMtQ31DcyMDJW0lFyDAISAYnFxUqxOigSrn44JFxcgYRbYmYOuoSfD7KEkb4RilEkSeA0Cr8E3LlIEmDnEpYw1jfWNzAywDSKIgmcduCUQI0PJAnU+CDGKNSwotwOiFGxAA==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Date = _t, Team = _t, #"PASS/FAIL" = _t]),
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Date", type text}, {"Team", type text}, {"PASS/FAIL", type text}}),
    #"Grouped Rows" = Table.Group(#"Changed Type", {"Date", "Team"}, {{"Count", each Table.RowCount(_), Int64.Type}}),
    Custom1 = List.Distinct( #"Grouped Rows"[Date]),
    #"Converted to Table" = Table.FromList(Custom1, Splitter.SplitByNothing(), {"Date"}, null, ExtraValues.Error),
    #"Added Custom" = Table.AddColumn(#"Converted to Table", "Team", each List.Distinct( #"Grouped Rows"[Team])),
    #"Expanded Team" = Table.ExpandListColumn(#"Added Custom", "Team"),
    #"Merged Queries" = Table.NestedJoin(#"Expanded Team", {"Date", "Team"}, #"Grouped Rows", {"Date", "Team"}, "Expanded Team", JoinKind.LeftOuter),
    #"Expanded Expanded Team" = Table.ExpandTableColumn(#"Merged Queries", "Expanded Team", {"Count"}, {"Count"}),
    #"Replaced Value" = Table.ReplaceValue(#"Expanded Expanded Team",null,0,Replacer.ReplaceValue,{"Count"})
in
    #"Replaced Value"

单步执行代码:

  1. 按日期和团队分组并创建计数:

    1. 获取不同的日期列表
    2. 转换为表格
    3. 为所有团队的交叉连接添加列(以便稍后获得零值)
    4. 展开
    5. 合并回分组步骤以拉入先前分组的值。
    6. 用 0 替换空值

    您可以通过在进行分组之前简单地过滤 pass 来修改您的其他问题。

【讨论】:

  • 非常感谢你的帮助。对于这个解决方案,我试过了,但由于某种原因,代码在从合并步骤扩展团队的步骤中被破坏了。你能澄清一下合并的目的吗?我看不到代码中的通过/失败,可以吗?
  • 将我的代码粘贴到一个空白查询中,它完全按照描述的方式工作,包括示例数据。然后您可以单击每个步骤来研究它并将其应用于您自己的问题。
  • 这段代码也很好用。我会尝试将它应用到我的查询中。太感谢了
【解决方案3】:

只需添加列,自定义列

= 1

然后单击选择通过/失败列,转换 .. 数据透视 .. 并选择新列

let  Source = Excel.CurrentWorkbook(){[Name="Table3"]}[Content],
#"Added Custom" = Table.AddColumn(Source, "Custom", each 1),
#"Pivoted Column" = Table.Pivot(#"Added Custom", List.Distinct(#"Added Custom"[PassFail]), "PassFail", "Custom", List.Sum)
in  #"Pivoted Column"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-10
    相关资源
    最近更新 更多