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

Earn a 50% discount on the DP-600 certification exam by completing the Fabric 30 Days to Learn It challenge.

Reply
Martine10
Frequent Visitor

For each group find first negative value and replace subsequent years with zero

Hello, how can I get the first negative number for each Group, Category and Country and then make the new value for that year and years after value zero?

 

GroupCategoryCountryYearValueNew value
1A120185050
1A120192020
1A12020-100
1A12021200

 

PS: It concerns a table with about 840.000 rows. (Groups (3) x categories (20) x countries (100) x years  (140). In terms of performance, it it best to do this in Power Query or in DAX? If I use a DAX measure I need to make sure the transformation is done on the group level so not aggregate countries and categories etc. 

3 REPLIES 3
smpa01
Super User
Super User

@Martine10  are you getting it from a SQL server? If there is no filter context involved for this task, doing the transformation server side will give you the optimimum performnace.

 

For example, in TSQL

declare @t1 as table (grp int,cat varchar(10), country int, year int, value int, row int) 
insert into @t1 
select 
  * 
from 
  (
    values 
      (1, 'A', 1, 2018, 50, 1), 
      (1, 'A', 1, 2019, 20, 2), 
      (1, 'A', 1, 2020,-10, 3), 
      (1, 'A', 1, 2021, 20, 4), 
      (1, 'B', 1, 2018, 50, 5), 
      (1, 'B', 1, 2019,-20, 6), 
      (1, 'B', 1, 2020,-10, 7), 
      (1, 'B', 1, 2021, 20, 8)
  ) t(a, b, c, d, e, f);
with cte1 as(
  select 
    grp, cat, country, year, value, row, 
    CASE when sum(value) over ( partition by grp, cat, country, year )< 0 then 0 else null end as _helper 
  from  @t1
) 
select 
  grp, cat, country, year, value, row, 
  CASE WHEN max(_helper) over(partition by grp, cat, country order by year rows unbounded preceding ) IS NULL then value 
      else max(_helper) over (partition by grp, cat, country order by year rows unbounded preceding ) end as Desired 
from cte1 
order by row

 

smpa01_0-1638467478005.png

 

Did I answer your question? Mark my post as a solution!
Proud to be a Super User!
My custom visualization projects
Plotting Live Sound: Viz1
Beautiful News:Viz1, Viz2, Viz3
Visual Capitalist: Working Hrs
CNENFRNL
Community Champion
Community Champion

Aside from calculated column with DAX, Table.MinN() in PQ easily does the trick in your scenario. Since the large dataset is logically sliced into many small ones, I expect the performance is satisfactory.

 

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("ddBJDsAgCAXQu7DGBBw6LHsOw/2vUaBNuuh3Yb74VBLmJCWmy1dkFT08hpDxT84MIH7IVBSSfo/qK+P5TvISAF1BlB1By/5Iem4BRJSGZPOAsC+7xMwqmd0=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Group = _t, Category = _t, Country = _t, Year = _t, Value = _t]),
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Year", Int64.Type}, {"Value", Int64.Type}}),
    #"Grouped Rows" = Table.Group(#"Changed Type", {"Group", "Category", "Country"}, {{"ar", each let tb = Table.MinN(_, "Year", each [Value] > 0), tb0 = Table.ReplaceValue(Table.Skip(_, Table.RowCount(tb)), each [Value], 0, Replacer.ReplaceValue, {"Value"}) in tb & tb0}}),
    #"Combined Tables" = Table.Combine(#"Grouped Rows"[ar])
in
    #"Combined Tables"

 

 


Thanks to the great efforts by MS engineers to simplify syntax of DAX! Most beginners are SUCCESSFULLY MISLED to think that they could easily master DAX; but it turns out that the intricacy of the most frequently used RANKX() is still way beyond their comprehension!

DAX is simple, but NOT EASY!

VahidDM
Super User
Super User

Hi @Martine10 

 

Try this code to add a new column to your table:

New value =
VAR _CY = [Year]
VAR _LY = _CY - 1
RETURN
    IF(
        [Value] < 0,
        0,
        IF(
            CALCULATE(
                MAX( 'Table'[Value] ),
                FILTER(
                    ALL( 'Table' ),
                    'Table'[Group] = EARLIER( 'Table'[Group] )
                        && 'Table'[Category] = EARLIER( 'Table'[Category] )
                        && 'Table'[Country] = EARLIER( 'Table'[Country] )
                        && 'Table'[Year] = _LY
                )
            ) < 0,
            0,
            [Value]
        )
    )

 

Output:

VahidDM_1-1638449677200.png

 

 

 

If this post helps, please consider accepting it as the solution to help the other members find it more quickly.
Appreciate your Kudos!!
LinkedIn: 
www.linkedin.com/in/vahid-dm/

 

 

Helpful resources

Announcements
LearnSurvey

Fabric certifications survey

Certification feedback opportunity for the community.

PBI_APRIL_CAROUSEL1

Power BI Monthly Update - April 2024

Check out the April 2024 Power BI update to learn about new features.

April Fabric Community Update

Fabric Community Update - April 2024

Find out what's new and trending in the Fabric Community.

Top Solution Authors