Excel电源查询中的复杂转换

Excel电源查询中的复杂转换,excel,powerquery,Excel,Powerquery,我有两个输入表。Input表1是源数据,Input表2是标准表 +--------------------------+----------+ +--------------------------+-------+ | TABLE 1 (Source data) | | TABLE 2 (Criterias) | +-------------------------------------+ +--------------------

我有两个输入表。Input表1是源数据,Input表2是标准表

+--------------------------+----------+  +--------------------------+-------+
|       TABLE 1 (Source data)         |  |       TABLE 2 (Criterias)        |
+-------------------------------------+  +----------------------------------+

+-------------------------------------+  +----------------------------------+
| DESCRIPTION              | VALUE    |  | PREFIX                   | CODE  |
+-------------------------------------+  +----------------------------------+
| ID                       | 0        |  | 7235                     | ABX1  |
| NAME                     | JFMSC    |  | 3553                     | POWQ  |
| TYPE                     | UHELQ    |  | 7459                     | UWEER |
| DFRUL                    | F4       |  | 10012                    | ABX1  |
| ADDR                     | 10012002 |  | 430                      | ABX1  |
| RRUL                     | P1       |  +--------------------------+-------+ 
| ADDR                     | 723      |  
| RRUL                     | P1       |  
| ID                       | 2        |  
| NAME                     | PLLSJS   |  
| TYPE                     | UHELQ    |  
| DFRUL                    | P3       |  
| ID                       | 4        |  
| NAME                     | AAAARR   |  
| TYPE                     | UHELQ    |  
| DFRUL                    | T7       |  
| ADDR                     | 35531156 |  
| RRUL                     | P1       |  
| ADDR                     | 72358    |  
| RRUL                     | P1       |  
| ADDR                     | 86401    |  
| RRUL                     | K9       |  
| ID                       | 0        |  
| NAME                     | PPROOA   |  
| TYPE                     | RRHN     |  
| DFRUL                    | P1       |  
| ADDR                     | 43001    |  
| RRUL                     | T8       |  
| ADDR                     | 7459001  |  
| RRUL                     | D4       |  
| ADDR                     | 430457   |  
| RRUL                     | W2       |  
| ADDR                     | 745913   |  
| RRUL                     | P1       |  
| ADDR                     | 74598001 |  
| RRUL                     | Y5       |  
+--------------------------+----------+
我的目标是得到如下输出表(即表4),即 根据“表2”的标准,显示了与每个字段“ADDR”的数量相比最相似的代码。 如果每个ID都有重复的代码,我只想显示一个(唯一代码列表)

我将在随附的示例文件中详细解释。

我想转换输入表1和表2中的数据,以获得如下输出表(所附文件中的所需输出表#2):


我希望有人能帮我。提前谢谢

下面是更新的解决方案

一般来说,我编译解决方案是为了尽可能减少数据问题的发生

对数据的唯一限制是:

  • 字段集必须具有ID字段,该字段必须是集合的第一个字段

  • 所有RRUL和ADDR必须成对

  • 一个ID内的RRUL/ADDR对的副本可接受或不存在

  • 我还编译了解决方案,以便在ADDR和PREFIX的所有可能变体中正确地找到最接近的值。顺便说一句,有一种情况在bigsample中没有涉及,即前缀比ADDR短,但不等于ADDR。如果存在这种情况,我的解决方案会正确处理它们,但在这种特殊情况下需要一些性能开销

    let
            Source = #"Source data",
        #"Added Index1" = Table.AddIndexColumn(Source, "Index", 0, 1),
    
        #"Added Custom" = Table.AddColumn(#"Added Index1", "Main Key", each if [DESCRIPTION] = "ID" then [Index] else null, type number),
    
        #"Added Custom10" = Table.AddColumn(#"Added Custom", "Last notADDR", each 
            if [DESCRIPTION] <> "ADDR" and [DESCRIPTION] <> "RRUL" then [Index] else null),
    
        #"Filled Down" = Table.FillDown(#"Added Custom10",{"Main Key", "Last notADDR"}),
    
        #"Added Custom2" = Table.AddColumn(#"Filled Down", "Key", each [Main Key] + (
            if [DESCRIPTION] = "RRUL" then [Index] - [Last notADDR] - 2 
                else if [DESCRIPTION] = "ADDR" then [Index] - [Last notADDR] - 1 else 0)),
    
        #"Removed Columns" = Table.RemoveColumns(#"Added Custom2",{"Index", "Main Key", "Last notADDR"}),
    
        #"Pivoted Column1" = Table.Pivot(#"Removed Columns", 
            List.Distinct(#"Removed Columns"[DESCRIPTION]), "DESCRIPTION", "VALUE"),
    
        #"Added Custom3" = Table.AddColumn(#"Pivoted Column1", "CODE", each if [ADDR] = null then null else let t = Table.AddIndexColumn(Table.SelectRows(Criterias, (x)=> 
            let s=List.Sort({x[PREFIX], [ADDR]}, each Text.Length(_)) in Text.StartsWith(s{1}, s{0})), "Index")
                in if Table.RowCount(t) > 0 then Table.First(Table.Sort(t, (y)=> Number.BitwiseShiftLeft(Number.Abs(Text.Length([ADDR]) - Text.Length(y[PREFIX])), 16) + y[Index]))[CODE] 
                else "Not Found"),
        #"Removed Columns1" = Table.RemoveColumns(#"Added Custom3",{"Key", "ADDR"}),
        #"Filled Down1" = Table.FillDown(#"Removed Columns1",{"ID", "NAME", "TYPE", "DFRUL"})
    in
        #"Filled Down1"
    
    let
    源=#“源数据”,
    #“Added Index1”=表AddIndexColumn(来源,“索引”,0,1),
    #“添加的自定义”=Table.AddColumn(#“添加的索引1”、“主键”,如果[DESCRIPTION]=“ID”,则为[Index]否则为空,类型号),
    #“添加的自定义10”=Table.AddColumn(#“添加的自定义”、“最后一个notADDR”,每个
    如果[DESCRIPTION]“ADDR”和[DESCRIPTION]“RRUL”,则[Index]否则为空,
    #“Filled Down”=Table.filledown(#“Added Custom10”,{“Main Key”,“Last notADDR”}),
    #“添加的Custom2”=Table.AddColumn(#“已填充”、“键”,每个[主键]+(
    如果[DESCRIPTION]=“RRUL”,则[Index]-[Last notADDR]-2
    否则,如果[DESCRIPTION]=“ADDR”,则[Index]-[Last notADDR]-1,否则为0),
    #“Removed Columns”=Table.RemoveColumns(#“Added Custom2”、{“Index”、“Main Key”、“Last notADDR”}),
    #“数据透视列1”=表.数据透视(#“已删除的列”,
    List.Distinct(#“已删除列”[DESCRIPTION]),“DESCRIPTION”,“VALUE”),
    #“Added Custom3”=Table.AddColumn(#“Pivoted Column1”,“CODE”,如果[ADDR]=null则为null,否则让t=Table.AddIndexColumn(Table.SelectRows(Criterias),(x)=>
    设s=List.Sort({x[前缀],[ADDR]},Text.StartsWith(s{1},s{0})),“Index”中的每个Text.Length(41;)
    在if Table.RowCount(t)>0中,然后是Table.First(Table.Sort(t,(y)=>Number.BitwiseShiftLeft(Number.Abs(Text.Length([ADDR])-Text.Length(y[前缀]),16)+y[索引])[代码]
    否则“未找到”),
    #“Removed Columns1”=Table.RemoveColumns(#“Added Custom3”、{“Key”、“ADDR”}),
    #“Filled Down1”=Table.FillDown(#“Removed Columns1”、{“ID”、“NAME”、“TYPE”、“DFRUL”})
    在里面
    #“已满1”
    
    这个问题的内容太多了。在我看来,您的主要问题是试图将完整地址与前缀匹配,因此我建议针对这一点发布更具体的问题。A是理想的。你已经有了很多细节,但如果它更专注、更简洁,它更有可能吸引解决方案,对未来的读者更有用。我理解,但如果我不把任何东西放在他们通常要求的输入和输出之外,他们会问,你做了什么?Hehe@Alexis奥尔森:我已经编辑了这个问题,我希望这样会更好。感谢Andrey,非常感谢您的回答,花点时间和更容易理解的详细清晰的代码。您的解决方案产生更接近的输出。我会尽快告诉你这些区别。嗨,安德烈,你的输出与我想要的输出相似,但在我的输出中代码只显示一次。在您的解决方案中,代码出现的次数与ADDR值与某些代码相关的次数相同。谢谢你的帮助。当做
    let
            Source = #"Source data",
        #"Added Index1" = Table.AddIndexColumn(Source, "Index", 0, 1),
    
        #"Added Custom" = Table.AddColumn(#"Added Index1", "Main Key", each if [DESCRIPTION] = "ID" then [Index] else null, type number),
    
        #"Added Custom10" = Table.AddColumn(#"Added Custom", "Last notADDR", each 
            if [DESCRIPTION] <> "ADDR" and [DESCRIPTION] <> "RRUL" then [Index] else null),
    
        #"Filled Down" = Table.FillDown(#"Added Custom10",{"Main Key", "Last notADDR"}),
    
        #"Added Custom2" = Table.AddColumn(#"Filled Down", "Key", each [Main Key] + (
            if [DESCRIPTION] = "RRUL" then [Index] - [Last notADDR] - 2 
                else if [DESCRIPTION] = "ADDR" then [Index] - [Last notADDR] - 1 else 0)),
    
        #"Removed Columns" = Table.RemoveColumns(#"Added Custom2",{"Index", "Main Key", "Last notADDR"}),
    
        #"Pivoted Column1" = Table.Pivot(#"Removed Columns", 
            List.Distinct(#"Removed Columns"[DESCRIPTION]), "DESCRIPTION", "VALUE"),
    
        #"Added Custom3" = Table.AddColumn(#"Pivoted Column1", "CODE", each if [ADDR] = null then null else let t = Table.AddIndexColumn(Table.SelectRows(Criterias, (x)=> 
            let s=List.Sort({x[PREFIX], [ADDR]}, each Text.Length(_)) in Text.StartsWith(s{1}, s{0})), "Index")
                in if Table.RowCount(t) > 0 then Table.First(Table.Sort(t, (y)=> Number.BitwiseShiftLeft(Number.Abs(Text.Length([ADDR]) - Text.Length(y[PREFIX])), 16) + y[Index]))[CODE] 
                else "Not Found"),
        #"Removed Columns1" = Table.RemoveColumns(#"Added Custom3",{"Key", "ADDR"}),
        #"Filled Down1" = Table.FillDown(#"Removed Columns1",{"ID", "NAME", "TYPE", "DFRUL"})
    in
        #"Filled Down1"