Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Microsoft is giving away 50,000 FREE Microsoft Certification exam vouchers. Get Fabric certified for FREE! Learn more

v-stephen-msft

Power Query 中的累加、条件累加

场景:

在 Power BI 中,我们有时会遇到累加问题。对于基本的直接累加,我们可以使用 Dax 语言或 M 语言。但对于条件累加和分组条件累加,我们倾向于使用 M 语言。下面将分三种情况逐步探讨累加求和:

1. 直接累加

2. 条件累加

3.分组条件累加

 

示例数据:

vstephenmsft_0-1735196650339.png

期望结果:

Part1.直接累加

vstephenmsft_1-1735196661457.png

Part2.条件累加

vstephenmsft_2-1735196683611.png

Part3.分组条件累加

vstephenmsft_3-1735196695619.png

Part1.直接累加

如果要在表格中累加 [净值],我们可以使用 list.accumulative(),具体操作如下:

1.添加索引列

vstephenmsft_4-1735196734291.png

2.自定义列

= List.Accumulate(List.FirstN( #"已添加索引"[净值],[索引]),0,(x, y) => x + y)

 

List.Accumulate() 函数需要三个参数、

第一个参数是 List,这里是 List.FirstN() 函数,用于提取列表的前 N 项;

第二个参数是初始值,这里设置为 0;

第三个参数是累加器函数。累加器函数中必须有两个值。一是累加器函数的当前状态值(用 x 表示),二是作为列表参数的当前项(用 y 表示);在 List.Accumulate 函数中的累加器函数首次运行前,状态参数值由初始值(0)中的值指定。

 

结合本例,List.Accumulate 的运行过程如下:

第一步,x= 0(第二个参数的初始值),y= 300(List 参数中的第一个项目)。然后执行累加器函数定义的计算逻辑:x + y:

第一次计算结果:x= 0,y= 300,x + y 相加后,将计算结果 300 赋值给 x,以取代原值。

第二次计算的结果:x= 300,y= -150,加上 x + y 后,计算结果 150 分配给 x 以代替原来的值。

第三次计算结果:x= 150,当前值=-200,加上 x + y 后,计算结果-50 赋值给 x 以替换原来的值。

......以此类推

 

3.结果

vstephenmsft_5-1735197071109.png

Part2.条件累加

在第 1 部分的基础上增加一个条件(如果总和小于 0,则从下一个数字开始重新求和)

1.添加索引列

vstephenmsft_6-1735197103285.png

2.添加自定义列

= List.Accumulate(

List.FirstN( #"已添加索引"[净值],[索引]),0,(x, y) => if x<0 then y else x + y)

 

只需在此处添加条件,如果 x 小于 0,就会重新计算

vstephenmsft_7-1735197113223.png

3.结果

vstephenmsft_8-1735197123460.png

Part3.分组条件累加

上述部分是在不分组的情况下累加的,那么如果是在分组的情况下累加呢?

1. 按组添加索引列

= Table.Group(#"排序的行", {"部分"}, {{"A", each Table.AddIndexColumn(_, "索引",1,1), type table}})

 

2.扩展它

vstephenmsft_9-1735197133788.pngvstephenmsft_10-1735197138292.png

3.添加 List.Generate() 函数

(values as list, grouping as list) as list =>

let

GRTList = List.Generate

(

()=> [ GRT = values{0}, i = 0 ],

each [i] < List.Count(values),

each try

if grouping{[i]} = grouping{[i] + 1}

then if [GRT]>0 then [GRT = [GRT] + values{[i] + 1}, i = [i] + 1] else [GRT = values{[i] + 1}, i = [i] + 1]

else [GRT = values{[i] + 1}, i = [i] + 1]

otherwise [i = [i] + 1]

,

each [GRT]

)

in

GRTList

 

List.Generate() 用于生成 List。

本例中,List.generate() 的第一个参数是一个包含两个变量的函数、

第一个变量 GRT=values{0} 是用于累加的变量 GRT 的初始值,也就是 [净值] 列的值;

第二个变量 i=0 在函数中用作递增序列,在这里表示第 i 行。[GRT=300, i =0]

传递给第二个参数的是一个条件函数,用于判断当前参与累加的行数是否少于数据的总行数。

如果满足第二个参数的条件,则传递给第三个参数--生成结果的规则,这里使用了两个 if 语句,第一个 if 判断组是否相同:

如果是同一组,则执行第二个判断:总和是否大于 0;如果大于 0,则总和为 [300+(-150),1] -->[300+(-150)+(-200),2] ;否则重置返回当前值 [-200,3];

如果不在同一组,那就改为 B 组,结果重置。

最后一个参数返回 GRT 列表。

 

4.将列合并成表

vstephenmsft_11-1735197313598.png

Table.FromColumns( 

    { 

      源[部分], A[索引], 源[净值], 源[日期], 

     FX(BufferedValues, Bufferedgroup) 

    }, 

    { 

      "部分", 

      "索引", 

      "净值","日期", 

       

      "总计" 

    }) 

按列建表,将各列合并为最终结果表。

FX 中的第一个参数是上一步 A 中的[净值]作为数值。

第二个参数是上一步 A 中作为分组的 [部分]。

 

5.结果

vstephenmsft_12-1735197358147.png

总结:

通过直接累加、条件累加和分组条件累加,我们可以逐步理解循环递归函数。当然,我们也可以根据不同的需要(不仅限于累加),替换条件和其他函数。

 

相关链接:已解决:回复:使用重置按组运行总计 - Microsoft Fabric Community

 

原作者:Yalan Wu
审核: Ula Huang, Kerry Wang

翻译:Fanfei Kong