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

Find everything you need to get certified on Fabric—skills challenges, live sessions, exam prep, role guidance, and more. Get started

Reply
Yiqian
Regular Visitor

How to combine raw table with with condition table in power query

Hello all Power BI experts,

 

Here I have a problem and I hope I can solve it with Power Query or power BI DAX.

I have two tables. One is raw data, that is like below,

 

CategoryValue
a70
b50
c40
d30
e60
f10
g

80

 

And I also have one table with conditions, that is, for example,

 

Customer NameCondition 1Condition 2Condition 3
Whiskya + b > 100a + b + c + d >200b + c + d + e >250

 

In fact, I have several customers and all of them may have 3 or more conditions to see if these values have met standards.

 

If a + b > 100, that is, they meet the condition 1, both a and b will multiple, for example, 0.05 and I will get a new value.

 

How can I do this with Power Query ?

Thanks!

 

Best Regards,

Yiqian

1 ACCEPTED SOLUTION

Check this:

 

Output

dufoq3_0-1723482593230.png

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WCs/ILM6uVNJRciwoyEkF0oYGBkqxOkgSTol5QAhkGKHL+Bcl5qWD9BhDZdwz85BMMjJFFkUohgoHZ6QWFaFYALMaLhOQmZcIMwwkFwsA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [#"Customer Name" = _t, Brand = _t, #"Sales volume" = _t]),
    ChangedType = Table.TransformColumnTypes(Source,{{"Sales volume", type number}}),
    Buffered = Table.Buffer(ChangedType),
    ConditionTable = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WCs/ILM6uVNJRciwoyElV0FZwSswDQoVHnUsVjAwMkCT8ixLz0lPBEiYoElAdKCrMgSpidaKV3DPzgCqRJIxMcZhpBpbIK83JAWsMzkgtKgK5C8k9hgZwJTCVsQA=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [#"Customer Name" = _t, #"Condition 1" = _t, #"Condition 2" = _t, #"Condition 3" = _t]),
    // You can probably delete this step.
    ReplaceTextNulls = Table.TransformColumns(ConditionTable, {}, each if _ = "null" then null else _),
    ReplacedValue = List.Accumulate(
        { {"≥", ">="}, {"≤", "<="} },
        ReplaceTextNulls, 
        (s,c)=> Table.ReplaceValue(s, c{0}, c{1}, Replacer.ReplaceText, Table.ColumnNames(s))
    ),
    Helper = [ conditionColumns = List.Select(Table.ColumnNames(ReplacedValue), (x)=> Text.StartsWith(x, "Condition", Comparer.OrdinalIgnoreCase)),
    delimiters = Text.ToList("+-/*><= ") ],
    StepBack = ReplacedValue,
    Ad_CheckColumns = List.Accumulate(
        Helper[conditionColumns],
        StepBack,
        (state, current)=> Table.AddColumn(state, current & " Check", each
                  [ a = Splitter.SplitTextByCharacterTransition((x)=> List.Contains(Helper[delimiters], x), (y)=> List.Contains(Helper[delimiters], y))(Record.Field(_, current)),
                    b = List.Transform(a, (x)=> [value = Table.SelectRows(Buffered, (y)=> y[Brand] = Text.Trim(x) and y[Customer Name] = [Customer Name]){0}?[Sales volume]?, result = if value = null then x else Text.From(value)][result]),
                    c = try Expression.Evaluate(Text.Combine(b)) otherwise null
                  ][c], type logical) ),
    UnpivotedOtherColumns = Table.UnpivotOtherColumns(Ad_CheckColumns, {"Customer Name"}, "Attribute", "Value"),
    FilteredRows = Table.SelectRows(UnpivotedOtherColumns, each Text.EndsWith([Attribute], "Check"))
in
    FilteredRows

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

4 REPLIES 4
PwerQueryKees
Resolver III
Resolver III

To keep it generic, I would do something like:

  • Create a table with one record for each customer
  • Put the M code of a function taking one record of your original table as parameter, returning true or false, in one of the colums. Call this column Validation.
  • Add a custome colum named "Validate", with Expression.Evaluate([Validation], #shared)
  • Mergejoin the new table with your original table on the customer id
  • Expand Validate column 
  • Add a new column with the expression [Validate](_)
  • Pivot the customer column with that Validate column as value

Doing this without acces to my laptop... So there will be errors... But hopefully this shows you a direction that is easily extendible for any number of customers.....

dufoq3
Super User
Super User

Hi @Yiqian, it is possible, but you should provide expected result based on sample data.

 

You can find some inspiration here:

 

dufoq3_0-1723198569546.png

 

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("Jca5DQAgEAOwXVJTgHh3OVHw778BkeLKZhhwqB7dGSab1cUmdbNRPWxRLxvUxza2fw==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Category = _t, Value = _t]),
    ChangedType = Table.TransformColumnTypes(Source,{{"Value", type number}}),
    Buffered = Table.Buffer(ChangedType),
    CustomersTable = #table(type table[Customer=text, Condition=text, Multiply Parameter=number], {{"Whisky", "a + b > 100", 0.05}}),
    Ad_Condition1 = Table.AddColumn(CustomersTable, "Condition 1", each 
        [ a = Text.SplitAny([Condition], "+-><=*/"), 
          b = List.Select(a, (x)=> not ((try Number.From(x) otherwise x) is number)),
          c = List.Transform(b, (x)=> { x, Table.SelectRows(Buffered, (y)=> y[Category] = Text.Trim(x))[Value]{0}? }),
          d = List.Accumulate(c, [Condition], (x,y)=> Text.Replace(x, Text.Trim(y{0}), Text.From(y{1})) ),
          e = List.Transform(c, (x)=> x{1}),
          g = if Expression.Evaluate(d) then List.Transform(e, (x)=> x * [Multiply Parameter]) else e
        ][g], type number)
in
    Ad_Condition1

 


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

@dufoq3 

Hi Friend, many thanks for your help! I think it's a quite useful way but I haven't wrote M Query Language directly in Power Query yet s it's somewhat difficult for me to transfer it to my work.

 

Here I want to post two tables more directly.

 

Table A is conditions related to sales volume.

For example,

 

Customer NameCondition 1Condition 2Condition 3
WhiskyApple + Banana ≥ 200Apple + Orange ≥ 400Apple + Banana + Orange ≥ 700
GinOrange ≥ 250Apple + Orange ≥ 650null
SherryBanana ≥ 100nullnull

 

Table B is related to customers and yearly sales volume.

For example as below

 

Customer NameBrandSales volume
WhiskyApple100
WhiskyBanana200
WhiskyOrange300
GinApple250
GinOrange350
SherryBanana100
SherryPinapple200

 

Up to now, I want to realize my first step, that is, to clean my data and follow up whether the sales volume has hit the condition 1/2/3 with a dashboard showing progress and percentage.

 

Your further help is highly appreciated.

 

Regards with many thanks,

Yiqian

Check this:

 

Output

dufoq3_0-1723482593230.png

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WCs/ILM6uVNJRciwoyEkF0oYGBkqxOkgSTol5QAhkGKHL+Bcl5qWD9BhDZdwz85BMMjJFFkUohgoHZ6QWFaFYALMaLhOQmZcIMwwkFwsA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [#"Customer Name" = _t, Brand = _t, #"Sales volume" = _t]),
    ChangedType = Table.TransformColumnTypes(Source,{{"Sales volume", type number}}),
    Buffered = Table.Buffer(ChangedType),
    ConditionTable = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WCs/ILM6uVNJRciwoyElV0FZwSswDQoVHnUsVjAwMkCT8ixLz0lPBEiYoElAdKCrMgSpidaKV3DPzgCqRJIxMcZhpBpbIK83JAWsMzkgtKgK5C8k9hgZwJTCVsQA=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [#"Customer Name" = _t, #"Condition 1" = _t, #"Condition 2" = _t, #"Condition 3" = _t]),
    // You can probably delete this step.
    ReplaceTextNulls = Table.TransformColumns(ConditionTable, {}, each if _ = "null" then null else _),
    ReplacedValue = List.Accumulate(
        { {"≥", ">="}, {"≤", "<="} },
        ReplaceTextNulls, 
        (s,c)=> Table.ReplaceValue(s, c{0}, c{1}, Replacer.ReplaceText, Table.ColumnNames(s))
    ),
    Helper = [ conditionColumns = List.Select(Table.ColumnNames(ReplacedValue), (x)=> Text.StartsWith(x, "Condition", Comparer.OrdinalIgnoreCase)),
    delimiters = Text.ToList("+-/*><= ") ],
    StepBack = ReplacedValue,
    Ad_CheckColumns = List.Accumulate(
        Helper[conditionColumns],
        StepBack,
        (state, current)=> Table.AddColumn(state, current & " Check", each
                  [ a = Splitter.SplitTextByCharacterTransition((x)=> List.Contains(Helper[delimiters], x), (y)=> List.Contains(Helper[delimiters], y))(Record.Field(_, current)),
                    b = List.Transform(a, (x)=> [value = Table.SelectRows(Buffered, (y)=> y[Brand] = Text.Trim(x) and y[Customer Name] = [Customer Name]){0}?[Sales volume]?, result = if value = null then x else Text.From(value)][result]),
                    c = try Expression.Evaluate(Text.Combine(b)) otherwise null
                  ][c], type logical) ),
    UnpivotedOtherColumns = Table.UnpivotOtherColumns(Ad_CheckColumns, {"Customer Name"}, "Attribute", "Value"),
    FilteredRows = Table.SelectRows(UnpivotedOtherColumns, each Text.EndsWith([Attribute], "Check"))
in
    FilteredRows

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

Helpful resources

Announcements
Europe Fabric Conference

Europe’s largest Microsoft Fabric Community Conference

Join the community in Stockholm for expert Microsoft Fabric learning including a very exciting keynote from Arun Ulag, Corporate Vice President, Azure Data.

AugPowerBI_Carousel

Power BI Monthly Update - August 2024

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

August Carousel

Fabric Community Update - August 2024

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

Top Solution Authors
Top Kudoed Authors