【问题标题】:How to filter a table by multiple (dynamic) conditions from another table?如何通过另一个表中的多个(动态)条件过滤一个表?
【发布时间】:2021-11-11 17:08:31
【问题描述】:

我一直在努力提高查询的灵活性。

我有事实表:

enabled country color count vehicle
yes DE yellow one car
no FR blue one car
no DE red one bike
yes DE green one car
yes ES yellow one car
yes IT yellow two car
yes IT yellow one car

在 Excel 中我还想要两个简单的配置表:

  1. 表:RemoveRecordsByValue 包含字段-值对的表,如果有任何匹配项,则作为删除这些记录的条件。
field value
vehicle bike
color green
color red
  1. 表:KeepRecordsByValue 一张桌子,可能
field value
country DE
country IT
count one

预期的表格是:

enabled country color count vehicle
yes DE yellow one car
yes IT yellow one car

任何人都可能有提示如何解决这个问题?

提前致谢,

***FactsTable***

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WqkwtVtJRcnEFEpWpOTn55UBGfl4qkExOLFKK1YlWyssHctyCgERSTmkqdmmw/qLUFLhsUmZ2Klgayfz0otTUPAz9EAWuwbgdAFHhGYKsoqQ8n4AKJDNiAQ==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [enabled = _t, country = _t, color = _t, count = _t, vehicle = _t]),
    Result = Table.TransformColumnTypes(Source,{{"enabled", type text}, {"country", type text}, {"color", type text}, {"count", type text}, {"vehicle", type text}})
in
    Result


***RemoveRecordsByValue***

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WKkvNyEzOSVXSUUrKzE5VitWJVkrOz8kvAgqkF6Wm5qGIFKWmKMXGAgA=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [field = _t, value = _t]),
    Result = Table.TransformColumnTypes(Source,{{"field", type text}, {"value", type text}})
in
    Result


***KeepRecordsByValue***

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WSs4vzSspqlTSUXJxVYrVQRbwDEEIALn5ealKsbEA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [field = _t, value = _t]),
    Result = Table.TransformColumnTypes(Source,{{"field", type text}, {"value", type text}})
in
    Result
´´´

【问题讨论】:

    标签: powerbi dax powerquery m


    【解决方案1】:

    可能有一百万种方法可以做到这一点。这是一个

    将 KeepRecordsByValue 和 RemoveRecordsByValue 作为单独的 powerquery 查询加载

    加载事实表。添加索引。单击选择索引并取消透视其他列。

    使用左外连接将事实表与 RemoveRecordsByValue 合并并展开一个字段。

    使用左外连接将结果与 KeepRecordsByValue 合并并展开一个字段。

    按索引对结果进行分组,并从上方组合展开的字段

    过滤掉 RemoveRecordsByValue 组合列中包含文本的任何内容以及 KeepRecordsByValue 组合列中包含空白的任何内容

    该表具有您要保留的唯一索引项。使用索引上的内部连接将其与原始事实表合并

    let Source = Excel.CurrentWorkbook(){[Name="Table3"]}[Content],
    #"Added Index" = Table.AddIndexColumn(Source, "Index", 0, 1),
    #"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Added Index", {"Index"}, "Attribute", "Value"),
    #"Merged Queries" = Table.NestedJoin(#"Unpivoted Other Columns",{"Attribute", "Value"},RemoveRecordsByValue,{"field", "value"},"RemoveRecordsByValue",JoinKind.LeftOuter),
    #"Expanded RemoveRecordsByValue" = Table.ExpandTableColumn(#"Merged Queries", "RemoveRecordsByValue", {"value"}, {"Remove"}),
    #"Merged Queries1" = Table.NestedJoin(#"Expanded RemoveRecordsByValue",{"Attribute", "Value"},KeepRecordsByValue,{"field", "value"},"KeepRecordsByValue",JoinKind.LeftOuter),
    #"Expanded KeepRecordsByValue" = Table.ExpandTableColumn(#"Merged Queries1", "KeepRecordsByValue", {"value"}, {"keep"}),
    Grouped= Table.Group(#"Expanded KeepRecordsByValue", {"Index"}, {{"Remove", each Text.Combine([Remove]," "), type text},{"Keep", each Text.Combine([keep]," "), type text}}),
    #"Filtered Rows" = Table.SelectRows(Grouped, each ([Remove] = "") and ([Keep] <> "")),
    #"Merged Queries2" = Table.NestedJoin(#"Added Index",{"Index"},#"Filtered Rows",{"Index"},"zzz",JoinKind.Inner),
    #"Removed Columns" = Table.RemoveColumns(#"Merged Queries2",{"Index", "zzz"})
    in  #"Removed Columns"
    

    【讨论】:

    • 嗨 horseyride,感谢您的反馈。使用连接是一种有趣的解决方法。我还没有考虑过,因为我试图不触及整个表格,直到我出于性能原因通过过滤来减少它。 (事实表是 2x 5 MB 外部 xlsx)明天去检查并尝试您的解决方案。我注意到一件事:KeepRecordsByValue 并不意味着保留任何值,但如果定义了一个字段,则其中一个值必须存在。即:如果定义了国家/地区,则记录必须使用 DE 或 IT,但其他记录无效。
    • 我一整天都试图解决它的方法是使用一个 Table.Select 为每个 KeepRecordsTable 和 RemoveRecordsTable 结合嵌套/递归 List.Contains 并通过使用它们的文本来引用 ColumnNames 或 RecordFields引用列(按字段)并与值进行比较。 ` filterTable = Table.SelectRows(factsTable, (row) => .....some recursive ........ (recordList, (columnToFilter) => List.Contains(columnToFilter[Value], Record.Field(row , columnToFilter[Field]) ))),
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-12
    • 2022-06-15
    相关资源
    最近更新 更多