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

The Power BI Data Visualization World Championships is back! Get ahead of the game and start preparing now! Learn more

Reply
datanalysis
New Member

Create a new column with calculation using conditions

Hi I have input data that looks like this, and I'd like to create a view with a new column "Month on Month Change", calculating difference on col "Actual" between current month and last month for items fall under the same "Segment". 

 

Input:

SegmentSectionMonthYearExpectedActualExpected VS ActualOwner
TransportationGeneral1+112023102993David
TransportationGeneral2+10202399100-1David
TransportationGeneral3+9202391910David
TransportationGeneral4+82023100991David
AccommodationGeneral1+1120236670-4John
AccommodationGeneral2+10202367681John
AccommodationGeneral3+9202367670John
AccommodationGeneral4+8202367661John

 

i.e: 

Month on Month change Row 1 = blank as there is no previous month data available for this segment

Month on Month change Row 2 = 1 (calculation being: select 'Segment - Transportation',  use 'Actual 2+10' - 'Actual 1+11')

SegmentSectionMonthYearExpectedActualExpected VS ActualOwnerMonth on month change
TransportationGeneral1+112023102993David 
TransportationGeneral2+10202399100-1David1

 

Following this logic, the full Output will look like:

SegmentSectionMonthYearExpectedActualExpected VS ActualOwnerMonth on month change
TransportationGeneral1+112023102993David 
TransportationGeneral2+10202399100-1David1
TransportationGeneral3+9202391910David-9
TransportationGeneral4+82023100991David8
AccommodationGeneral1+1120236670-4John 
AccommodationGeneral2+10202367681John-2
AccommodationGeneral3+9202367670John-1
AccommodationGeneral4+8202367661John-1

 

Is there a way to acheive this in PowerQuery?

2 ACCEPTED SOLUTIONS
AlienSx
Super User
Super User

    s = your_table,
    f = (tbl) => 
        [rows = List.Buffer(Table.ToRecords(Table.Sort(tbl, "Month"))), 
        gen = List.Generate(
            () => [i = 0, r = rows{0} & [Month on month change = 0]],
            (x) => x[i] < List.Count(rows),
            (x) => [i = x[i] + 1, r = rows{i} & [Month on month change = rows{i}[Actual] - x[r][Actual]]],
            (x) => x[r]
        )][gen],
    group = Table.Group(s, "Segment", {"x", f}),
    z = Table.FromRecords(List.Combine(group[x]))

View solution in original post

dufoq3
Super User
Super User

Hi @datanalysis, different approach here.

 

Result

dufoq3_0-1714673044213.png

let
    fnShift = (tbl as table, col as text, shift as nullable number, optional newColName as text, optional _type as type) as table =>
        //v 3. parametri zadaj zaporne cislo ak chces posunut riadky hore, kladne ak dole, 4. je nepovinny (novy nazov stlpca), 5. je nepovinny typ
        let
            a = Table.Column(tbl, col),
            b = if shift = 0 or shift = null then a else if shift > 0
                then List.Repeat({null}, shift) & List.RemoveLastN(a, shift)
                else List.RemoveFirstN(a, shift * -1) & List.Repeat({null}, shift * -1),    
            c = Table.FromColumns(Table.ToColumns(tbl) & {b}, Table.ColumnNames(tbl) &
                ( if newColName <> null then {newColName} else
                    if shift = 0 then {col & "_Duplicate"} else
                    if shift > 0 then {col & "_PrevValue"} 
                    else              {col & "_NextValue"} )),
            d = Table.TransformColumnTypes(c, {List.Last(Table.ColumnNames(c)), if _type <> null then _type else type any})
        in
            d,
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WCilKzCsuyC8qSSzJzM9T0lFyT81LLUrMAbIMtQ0NgZSRgZExiGdgBCQtLYEEiOuSWJaZohSrg9cEI21DA4QJYL2GBiARXUNijTDWtkQywRBGGBCr30TbAtkPBnB3oBjgmJycn5ubn0IoEMzMgIQ52AcmQMIrPyOPgH7UIDAzBxEWUPuJ0I7ifYhuc6j3idCN4nmIbjMUu2MB", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Segment = _t, Section = _t, Month = _t, Year = _t, Expected = _t, Actual = _t, #"Expected VS Actual" = _t, Owner = _t]),
    ChangedType = Table.TransformColumnTypes(Source,{{"Year", Int64.Type}, {"Expected", type number}, {"Actual", type number}, {"Expected VS Actual", type number}}),
    GroupedRows = Table.Group(ChangedType, {"Segment"}, {{"All", each 
        [ a = fnShift(_,"Actual",1, null, type number),
          b = Table.AddColumn(a, "Month on month change", (x)=> x[Actual] - x[Actual_PrevValue], type number),
          c = Table.RemoveColumns(b, {"Actual_PrevValue"})
        ][c], type table}}),
    CombinedAll = Table.Combine(GroupedRows[All])
in
    CombinedAll

Note: Check this link to learn how to use my query.
Check this link if you don't know how to provide sample data.

View solution in original post

2 REPLIES 2
dufoq3
Super User
Super User

Hi @datanalysis, different approach here.

 

Result

dufoq3_0-1714673044213.png

let
    fnShift = (tbl as table, col as text, shift as nullable number, optional newColName as text, optional _type as type) as table =>
        //v 3. parametri zadaj zaporne cislo ak chces posunut riadky hore, kladne ak dole, 4. je nepovinny (novy nazov stlpca), 5. je nepovinny typ
        let
            a = Table.Column(tbl, col),
            b = if shift = 0 or shift = null then a else if shift > 0
                then List.Repeat({null}, shift) & List.RemoveLastN(a, shift)
                else List.RemoveFirstN(a, shift * -1) & List.Repeat({null}, shift * -1),    
            c = Table.FromColumns(Table.ToColumns(tbl) & {b}, Table.ColumnNames(tbl) &
                ( if newColName <> null then {newColName} else
                    if shift = 0 then {col & "_Duplicate"} else
                    if shift > 0 then {col & "_PrevValue"} 
                    else              {col & "_NextValue"} )),
            d = Table.TransformColumnTypes(c, {List.Last(Table.ColumnNames(c)), if _type <> null then _type else type any})
        in
            d,
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WCilKzCsuyC8qSSzJzM9T0lFyT81LLUrMAbIMtQ0NgZSRgZExiGdgBCQtLYEEiOuSWJaZohSrg9cEI21DA4QJYL2GBiARXUNijTDWtkQywRBGGBCr30TbAtkPBnB3oBjgmJycn5ubn0IoEMzMgIQ52AcmQMIrPyOPgH7UIDAzBxEWUPuJ0I7ifYhuc6j3idCN4nmIbjMUu2MB", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Segment = _t, Section = _t, Month = _t, Year = _t, Expected = _t, Actual = _t, #"Expected VS Actual" = _t, Owner = _t]),
    ChangedType = Table.TransformColumnTypes(Source,{{"Year", Int64.Type}, {"Expected", type number}, {"Actual", type number}, {"Expected VS Actual", type number}}),
    GroupedRows = Table.Group(ChangedType, {"Segment"}, {{"All", each 
        [ a = fnShift(_,"Actual",1, null, type number),
          b = Table.AddColumn(a, "Month on month change", (x)=> x[Actual] - x[Actual_PrevValue], type number),
          c = Table.RemoveColumns(b, {"Actual_PrevValue"})
        ][c], type table}}),
    CombinedAll = Table.Combine(GroupedRows[All])
in
    CombinedAll

Note: Check this link to learn how to use my query.
Check this link if you don't know how to provide sample data.

AlienSx
Super User
Super User

    s = your_table,
    f = (tbl) => 
        [rows = List.Buffer(Table.ToRecords(Table.Sort(tbl, "Month"))), 
        gen = List.Generate(
            () => [i = 0, r = rows{0} & [Month on month change = 0]],
            (x) => x[i] < List.Count(rows),
            (x) => [i = x[i] + 1, r = rows{i} & [Month on month change = rows{i}[Actual] - x[r][Actual]]],
            (x) => x[r]
        )][gen],
    group = Table.Group(s, "Segment", {"x", f}),
    z = Table.FromRecords(List.Combine(group[x]))

Helpful resources

Announcements
Power BI DataViz World Championships

Power BI Dataviz World Championships

The Power BI Data Visualization World Championships is back! Get ahead of the game and start preparing now!

December 2025 Power BI Update Carousel

Power BI Monthly Update - December 2025

Check out the December 2025 Power BI Holiday Recap!

FabCon Atlanta 2026 carousel

FabCon Atlanta 2026

Join us at FabCon Atlanta, March 16-20, for the ultimate Fabric, Power BI, AI and SQL community-led event. Save $200 with code FABCOMM.

Top Solution Authors