If statement 电源查询:当一个特定值出现在另一列中时,如何将一个添加到一列中

If statement 电源查询:当一个特定值出现在另一列中时,如何将一个添加到一列中,if-statement,powerbi,increment,powerquery,m,If Statement,Powerbi,Increment,Powerquery,M,我有一个ID列,每次在我的Geography列(ItalyZ、ItalyM、UKY或UKM)中发现特定项目时,我都在寻找增加ID的方法 ItalyZ的ID从0开始,到4000结束 ItalyB的ID从4000开始,到8000结束 UKY的ID从0开始,到4000结束 UKM的ID从4000开始,到8000结束 然而,我正在刷新我的文件,因此,我将不时地有新的“地理”到达,而没有来源或第一个ID。这些边界/范围仅为已知的起点和终点 以下是我的数据示例: |-------------------

我有一个ID列,每次在我的
Geography
列(
ItalyZ
ItalyM
UKY
UKM
)中发现特定项目时,我都在寻找增加ID的方法

ItalyZ
的ID从0开始,到4000结束

ItalyB的ID从4000开始,到8000结束

UKY
的ID从0开始,到4000结束

UKM
的ID从4000开始,到8000结束

然而,我正在刷新我的文件,因此,我将不时地有新的“地理”到达,而没有来源或第一个ID。这些边界/范围仅为已知的起点和终点

以下是我的数据示例:

  |---------------------|------------------|    
  |       ID            |   Geography      |
  |---------------------|------------------|
  |    AB0000           |      ItalyZ      |
  |---------------------|------------------|
  |    AB4041           |      ItalyB      |
  |---------------------|------------------|
  |    BC0000           |      UKY         |
  |---------------------|------------------|
  |    BC4001           |      UKM         |
  |---------------------|------------------|
  |    NULL             |      ItalyZ      |
  |---------------------|------------------|
  |    NULL             |      ItalyZ      |
  |---------------------|------------------|
  |    NULL             |      UKY         |
  |---------------------|------------------|
  |    NULL             |      UKM         |
  |---------------------|------------------|  
以下是我的预期输出:

  |---------------------|------------------|    
  |       ID            |   Geography      |
  |---------------------|------------------|
  |    AB0000           |      ItalyZ      |
  |---------------------|------------------|
  |    AB4041           |      ItalyB      |
  |---------------------|------------------|
  |    BC0000           |      UKY         |
  |---------------------|------------------|
  |    BC4001           |      UKM         |
  |---------------------|------------------|
  |    AB0001           |      ItalyZ      |
  |---------------------|------------------|
  |    AB0001           |      ItalyZ      |
  |---------------------|------------------|
  |    AB4042           |      UKY         |
  |---------------------|------------------|
  |    BC0001           |      UKM         |
  |---------------------|------------------|  
我一直在尝试许多不同的方法,并试图适应运行总体解决方案。我还尝试将我的文件分为四个不同的部分,以避免在不同的情况下交替使用If函数,从而使其更简单,如我的power query中所示:

 #"Added Custom2" = Table.AddColumn(#"Reordered Columns", "Sum", each if [Geography] = "UKM" then [Number AB range below 4000] + 1 
else if [Geography] = "UKY" then [Number AB range above 4000] + 1 
else if [Geography] = "ItalyB" then [Number BC range above 5000]
else [Number BC range below 5000] + 1)

但绝对没有任何效果。这真让人发疯

我将回答一个进一步简化的问题,因为我不想处理
ID
字母前缀

假设我们有下表(包括:

ID,  Group
-----------
0,     A
1,     A
300,   B
525,   C
null,  A
null,  B
null,  B
null,  C
并希望生成一个新列
NewID
,该列将替换
ID

ID,  Group, NewID
------------------
0,     A,   0
1,     A,   1
300,   B,   300
525,   C,   525
null,  A,   2
null,  B,   301
null,  B,   302
null,  C,   526
下面是一个使用
表的方法。AddIndexColumn

let
    Source = <First Table Above>,
    #"Grouped Rows" = Table.Group(Source, {"Group"}, {{"ID", each List.Max([ID]), type number}}),
    #"Added Custom" = Table.AddColumn(#"Grouped Rows", "Custom", (C) => Table.AddIndexColumn(Table.SelectRows(Source, each _[Group] = C[Group]),"NewID",C[ID],1)),
    #"Expanded Custom" = Table.ExpandTableColumn(#"Added Custom", "Custom", {"NewID"}, {"NewID"}),
    #"Removed Columns" = Table.RemoveColumns(#"Expanded Custom",{"ID"})
in
    #"Removed Columns"
复杂的步骤只发生了一点变化:

(C) => Table.AddIndexColumn(
           Table.SelectRows(
               Table.Sort(#"Added Index", {"ID"}),
               each _[Group] = C[Group]
           ),
           "NewID", C[ID] + 1, 1
       )
不同之处在于,我们需要添加一个排序,以便空值位于所有已分配的
ID
值之后,并在
C[ID]+1
处开始索引空值,而不仅仅是
C[ID]


这是一个步骤较少(无分组、展开或合并)但功能更复杂的版本:

let
    Source = <First Table Above>,    
    #"Added Index" = Table.AddIndexColumn(Source, "Index", 0, 1),
    #"Added Custom" = Table.AddColumn(#"Added Index", "Custom", (C) => Table.SelectRows(#"Added Index", each _[Group] = C[Group])),
    #"Added NewID" = Table.AddColumn(#"Added Custom", "NewID", (C) => if C[ID] = null then Table.SelectRows(Table.AddIndexColumn(Table.SelectRows(C[Custom], each _[ID] = null), "NewID", List.Max(C[Custom][ID])+1,1), each _[Index] = C[Index]){0}[NewID] else C[ID]),
    #"Removed Columns" = Table.RemoveColumns(#"Added NewID",{"Custom"})
in
    #"Removed Columns"

与之前类似,我们使用组子表
Custom
,只需选择空
ID
行,并从最大非空
ID
加上一开始对它们进行索引。这仍然留给我们一个表,因此我们只需要该子表中对应于整个表中
索引的行。我们使用
{0}[NewID]
[NewID]
列中表中第一(唯一)行的单元格中提取值。对于非空
ID
值,else子句将其保持原样。

与我的另一个答案一样,这里有一个简化的问题,忽略您的
ID
字母前缀

ID,  Group | NewID
-----------|------
4,     A   | 4
7,     A   | 7
300,   B   | 300
525,   C   | 525
null,  A   | 10
9,     A   | 9
null,  A   | 11
null,  B   | 301
null,  C   | 526
null,  A   | 12
null,  B   | 302
从表的左侧开始,我们要计算新列
NewID

ID,  Group, NewID
------------------
0,     A,   0
1,     A,   1
300,   B,   300
525,   C,   525
null,  A,   2
null,  B,   301
null,  B,   302
null,  C,   526
在这个答案中,我将编写一个自定义函数,该函数使用该函数递归编写

从链接的文档中,函数设置如下

List.Generate(
    initial as function,                    /*Set all your initial variables*/
    condition as function,                  /*Stopping criteria.*/
    next as function,                       /*Define how to update at each step.*/
    optional selector as nullable function  /*Pick output element.*/
) as list
定义一个函数,该函数接受可能包含null的列,并从最大非null值递增填充null:

(Column as list) as list =>
let
    Generate =
    List.Generate(
        () => [x = Column{0}, i = 0, n = List.Max(Column)],
        each [i] < List.Count(Column),
        each [
            i = [i] + 1,
            x = if Column{i} = null then [n] + 1 else Column{i},
            n = if Column{i} = null then [n] + 1 else [n]
            ],     
        each [x]
    )
in
    Generate
以下是分组后但展开前的外观:

注意函数的作用。我们正在为每个单独的
应用
ID
列上的
FillNulls



这与另一个答案的步骤和复杂程度相似,但使用的函数是以递归方式构造的,您可能更熟悉。

不断发布然后反复删除同一问题的变体不是一件好事。对不起,我意识到它的表述很差。我将更新并返回但我确实试图最终完全、绝对地理解power query中的条件计数/求和。我希望能够绝对地理解它。有没有办法重新更新线程中的问题?例如,如果策略是制定并彻底查看问题的所有潜在解决方案?嗨,我非常感谢你。我有点沮丧,因为它对我来说很复杂。因此我问:这真的很复杂吗?我正在努力理解它。(1)首先添加一个索引,然后用最大值对行进行分组(从而用最大值生成一个新表),(2)然后扩展列和(3)将其与第一个表合并,仅使用匹配值(左外)?(4)最后添加一列,在某些情况下替换“ID”(为什么?)。我很抱歉我的问题…(1)✓ (2) ✓ (3) 这是一对一的匹配。内部连接也可以。(4)如果现有的
ID
值不是连续的,我们只替换原始表中的null
ID
值。如果它们是连续的,或者您不需要保留原始
ID
,那么您可以使用第一种更简单的方法(使用min而不是max)。您可能更喜欢我刚刚编辑的步骤较少的替代公式。再次感谢。但是,我仍然有点难以理解这些步骤,最重要的是为什么这样做要比在excel中痛苦得多。我已经尝试阅读参考资料并理解其原因…我确信有充分的理由…但我正在努力。我我明白,M的这种设置可以实现更高的安全性和质量…我还读到,这会导致PBI的性能变慢,对于更大的数据集…这对我来说太可怕了。我希望我能真正理解这一点。再次感谢你。我还无法理解。但是,我也不知道更简单的选项,步骤更少(没有分组、扩展或合并)。再次感谢。我仍然很遗憾没有得到它…我理解函数构造,但当我尝试测试、调整和玩游戏时,我得到了“fx”它出现在Power BI中,要求我输入特定的参数……这是正确的。您在实际查询中使用了我指定的函数。好处是它可以用于多个查询。您可能需要将该查询更改为使用
fx
,而不是
FillNulls
,如果这是您命名的函数。是的,sim
(Column as list) as list =>
let
    Generate =
    List.Generate(
        () => [x = Column{0}, i = 0, n = List.Max(Column)],
        each [i] < List.Count(Column),
        each [
            i = [i] + 1,
            x = if Column{i} = null then [n] + 1 else Column{i},
            n = if Column{i} = null then [n] + 1 else [n]
            ],     
        each [x]
    )
in
    Generate
let
    Source = <Data Table Source Here>,
    #"Grouped Rows" = Table.Group(Source, {"Group"}, {{"FillNulls", each FillNulls([ID]), type list}}),
    #"Expanded FillNulls" = Table.ExpandListColumn(#"Grouped Rows", "FillNulls")
in
    #"Expanded FillNulls"