I have a sales table of 5 products for multiple years and regions. I am struggling to get the biggest sales product year over year with Power BI. I know that I can group by year and get the total sales of each product, but what is the best way to extract which product had the biggest sales year over year? I have created a sample table:
Year
Region
Product A
Product B
Product C
Product D
Product E
2019
America
65
71
40
80
24
2020
America
50
56
36
44
45
2021
America
80
44
48
75
49
2022
America
90
65
55
52
99
2019
Asia
45
20
23
73
51
2020
Asia
55
33
54
52
50
2021
Asia
36
26
70
35
48
2022
Asia
23
64
77
28
28
2019
Europe
66
31
70
51
88
2020
Europe
56
66
8
60
53
2021
Europe
70
30
13
78
71
2022
Europe
89
78
45
67
80
PS: I have missing data in some of the cells, I am using null for those sells, would that change the calculation?
See if this works for you
EDIT: It finds the Product in each year that has the greatest growth between that year and the next year ignoring region
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Year", Int64.Type}, {"Region", type text}, {"Product A", Int64.Type}, {"Product B", Int64.Type}, {"Product C", Int64.Type}, {"Product D", Int64.Type}, {"Product E", Int64.Type}}),
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Changed Type", {"Year", "Region"}, "Attribute", "Value"),
#"Grouped Rows1" = Table.Group(#"Unpivoted Other Columns", {"Year", "Attribute"}, {{"Value", each List.Sum([Value]), type number}}),
#"Added Custom" = Table.AddColumn(#"Grouped Rows1", "NextYear", each [Year]+1),
#"Merged Queries" = Table.NestedJoin(#"Added Custom", {"Attribute", "NextYear"}, #"Added Custom", {"Attribute", "Year"}, "Added Custom", JoinKind.LeftOuter),
#"Expanded Added Custom1" = Table.ExpandTableColumn(#"Merged Queries", "Added Custom", {"Value"}, {"Next.Value"}),
#"Filtered Rows" = Table.SelectRows(#"Expanded Added Custom1", each ([Next.Value] <> null)),
#"Added Custom1" = Table.AddColumn(#"Filtered Rows", "Diff", each if [Next.Value]=null then null else [Next.Value]-[Value]),
#"Grouped Rows" = Table.Group(#"Added Custom1", {"Year"}, {{"data", each Table.LastN(Table.Sort(_,{{"Diff", Order.Ascending}}),1), type table }}),
#"Expanded data" = Table.ExpandTableColumn(#"Grouped Rows", "data", {"NextYear","Attribute" }, {"NextYear","Attribute"})
in #"Expanded data"
It finds the Product in each year/region that has the greatest growth between that year and the next year
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Year", Int64.Type}, {"Region", type text}, {"Product A", Int64.Type}, {"Product B", Int64.Type}, {"Product C", Int64.Type}, {"Product D", Int64.Type}, {"Product E", Int64.Type}}),
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Changed Type", {"Year", "Region"}, "Attribute", "Value"),
#"Added Custom" = Table.AddColumn(#"Unpivoted Other Columns", "NextYear", each [Year]+1),
#"Merged Queries" = Table.NestedJoin(#"Added Custom", {"Region", "NextYear"}, #"Added Custom", {"Region", "Year"}, "Added Custom", JoinKind.LeftOuter),
#"Expanded Added Custom" = Table.ExpandTableColumn(#"Merged Queries", "Added Custom", {"Value"}, {"Added Custom.Value"}),
#"Added Custom1" = Table.AddColumn(#"Expanded Added Custom", "Diff", each if [Added Custom.Value]=null then null else [Added Custom.Value]-[Value]),
#"Grouped Rows" = Table.Group(#"Added Custom1", {"Region", "Year"}, {{"data", each Table.LastN(Table.Sort(_,{{"Diff", Order.Ascending}}),1), type table }}),
#"Expanded data" = Table.ExpandTableColumn(#"Grouped Rows", "data", {"NextYear","Attribute", "Diff"}, {"NextYear","Attribute", "Diff"}),
#"Filtered Rows" = Table.SelectRows(#"Expanded data", each ([Diff] <> null))
in #"Filtered Rows"
Focusing on another approach I made this M code, which lists the 'TopSeller' values by year/region/product:
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
Unpivoted = Table.Unpivot(Source, {"Product A", "Product B", "Product C", "Product D", "Product E"}, "Product", "Amount"),
SortedRows = Table.Sort(Unpivoted,{{"Year", Order.Ascending}, {"Region", Order.Ascending}, {"Product", Order.Ascending}, {"Amount", Order.Descending}}),
GroupedRows = Table.Group(SortedRows, {"Product", "Year"}, {{"Count", each List.Sum([Amount]), type number}, {"Details", each _, type table [Year=number, Region=text, Product=text, Amount=number, Índice Geral=number]}}),
AddedCustom = Table.AddColumn(GroupedRows, "TopSeller", each Table.Max([Details],"Amount")),
TopValueExpanded = Table.ExpandRecordColumn(AddedCustom, "TopSeller", {"Year", "Region", "Product", "Amount"}, {"TopSeller.Year", "TopSeller.Region", "TopSeller.Product", "TopSeller.Amount"}),
SortedRows2 = Table.Sort(TopValueExpanded,{{"TopSeller.Year", Order.Ascending}, {"TopSeller.Region", Order.Ascending}, {"TopSeller.Product", Order.Ascending}}),
GroupedRows2 = Table.Group(SortedRows2, {"TopSeller.Region", "TopSeller.Product"}, {{"Count", each _, type table [Product=text, Year=number, Count=number, Details=table, TopSeller.Year=number, TopSeller.Region=text, TopSeller.Product=text, TopSeller.Amount=number]}}),
CountExpanded = Table.ExpandTableColumn(GroupedRows2, "Count", {"Year", "TopSeller.Amount"}, {"Year", "TopSeller.Amount"}),
SortedRows3 = Table.Sort(CountExpanded,{{"Year", Order.Ascending}}),
ReorderedColumns = Table.ReorderColumns(SortedRows3,{"Year", "TopSeller.Region", "TopSeller.Product", "TopSeller.Amount"}),
FinalRanking = Table.Sort(ReorderedColumns,{{"Year", Order.Ascending}, {"TopSeller.Product", Order.Ascending}})
in
FinalRanking
Related
I want to transform a column in Power query. Only the transformation should be applied within the group based on a condition. This is my data.
Here in the above table, I just want to transform Office based column to all 1 if any Office-based column is set to 1 on the particular ID group. But all the Office based column value is 0 on the particular ID group, it should not transform the column.
My expected result would be,
It would be fine, If an additional column can have the transformed column.
try this
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"ID", type text}, {"Item", type text}, {"Home Based", Int64.Type}, {"Office Based", Int64.Type}, {"Amount", Int64.Type}}),
// find all IDs with 1 in Office Based
#"Filtered Rows" = Table.SelectRows(#"Changed Type", each ([Office Based] = 1)),
#"Removed Other Columns" = Table.SelectColumns(#"Filtered Rows",{"ID"}),
#"Removed Duplicates" = Table.Distinct(#"Removed Other Columns"),
//merge that back in
#"Merged Queries" = Table.NestedJoin(#"Changed Type", {"ID"}, #"Removed Duplicates", {"ID"}, "Table2", JoinKind.LeftOuter),
#"Expanded Table2" = Table.ExpandTableColumn(#"Merged Queries", "Table2", {"ID"}, {"ID.1"}),
// if there was a match convert to 1 otherwise take original number
#"Added Custom" = Table.AddColumn(#"Expanded Table2", "OfficeBased2", each try if Text.Length([ID.1])>0 then 1 else [Office Based] otherwise [Office Based]),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"Office Based", "ID.1"}),
#"Renamed Columns" = Table.RenameColumns(#"Removed Columns",{{"OfficeBased2", "OfficeBased"}})
in #"Renamed Columns"
or the more compact version:
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Added Custom" = Table.AddColumn(Source,"Custom",(i)=>Table.SelectRows(Source, each [ID]=i[ID]) [Office Based]),
#"Added Custom1" = Table.AddColumn(#"Added Custom", "Office Based2", each if List.Contains([Custom],1) then 1 else [Office Based]),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom1",{"Custom", "Office Based"})
in #"Removed Columns"
The first method probably works best for large data sets
Here's another method:
Group by ID
Apply the Table.TransformColumns operation to each subtable
Then re-expand
let
Source = Excel.CurrentWorkbook(){[Name="Table2"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"ID", type text}, {"Item", type text}, {"Home Based", Int64.Type}, {"Office Based", Int64.Type}, {"Amount", Int64.Type}}),
#"Grouped Rows" = Table.Group(#"Changed Type", {"ID"}, {
{"Xform", (t)=>Table.TransformColumns(t, {
{"Office Based", each if List.ContainsAny(t[Office Based],{1}) then 1 else 0}}) ,
type table
[ID=nullable text, Item=nullable text, Home Based=nullable number, Office Based=nullable number, Amount=nullable number]}
}),
#"Expanded Xform" = Table.ExpandTableColumn(#"Grouped Rows", "Xform",
{"Item", "Home Based", "Office Based", "Amount"},
{"Item", "Home Based", "Office Based", "Amount"})
in
#"Expanded Xform"
i've got a datasheet with a bunch of tasks, their start/end time, duration and start day.
Task
Start Time
End Time
Duration
Start Day
Task1
21:00
22:15
1:15
Monday
Task1
21:20
23:30
2:10
Monday
Task2
23:00
23:20
0:20
Tuesday
What I'm trying to do is put this data into a new calculated table that would split each task and plot a new row for the mins spent in each hour, as determined by the duration. For example:
Task
Hour
Mins in Hour
Start Day
Task1
21
60
Monday
Task1
22
15
Monday
Task1
21
40
Monday
Task1
22
60
Monday
Task1
23
30
Monday
Task2
23
20
Tuesday
I'm having no luck, could anyone help please?
Can be done with PQ
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("tZg9bhwxDIXv4tqFSEkzs3uHVHFnuDCQVAGSwnCR20cSn2YkhtLsxk5FwP6WoB5/xNHz88PT69sPenh8YHf1TmxYknXuStk+vX9/+/b6++HlUVgWhgpL15ito2twY9a55jcO9oStMQQrBt+z7iJssZoN6W90UWcj+2xgS3zJMvzSxK+rLM7G1tk0i7PxJIbb/W5ytmoddBmwVHORc+746mjMOvh1Hn79iF2vIUK7KPr6YQwr/K435O3fWDkbzmiyC+JNdoVfHrOib7LwO9ZsQe0kPTbosI1ZB78BfoPl17M6XMDhsv3y6+eMdWDdLWybZJNtRLuc+T1Ei4iBJ2wVTdg0TCZsFa1rohM2RmGLPfOLZBRrshFnS5rVYh/6jfAbrwx9eahvw040y2FRQCoO1F+GqEQbJMqcNSPa+1FCrFILZAYQBXXw6tr+0RIodFa54Q63d7MerO/bUrElYSzTLttl7HYDgggYg5cM9CKoU6hVih3K/chT6NKjs0bXKDfD8QSdCFtQXAnZngVwFyopSChipXWIOniNmPnRQDn/jbCjZJYwkqwi2IQVv26qQdklWra9q3Uhlv9hZ0k2TJIrdxL2hWzrfWacTSRq2A3sZrC+YfNoKhNhMSdCaZxb/UbFznRYFDsbCoXFfpPYbi8dsOJ3m2tW2HW/ziSGtGsNYwCb7aR9enZDjsnOsWIdpo23rj4dwywXYB3YWV9olsHyp7Lbfp0E4zoRdpGc7r/BbjxgRYcF+5g9Hnr22B+tntdsjcHfEEOcrQA63vZbacDKrn3EEIzeZKCQV1LMsvbaqEMEVBUzKqdDawBkNrFGUefmjMz/iiq9ZKYXqFeolQWgFFuBcW/YqHiL07mg0boAGC2p0Fk3FBTLXbKxDsdRrFjD8rE2SSwb2SK463PgzRz07HxhEhYLU7Kzk2k2orriMF6vyiuY5SUsQzLee8yad5WVEuD+neOErfGO9W3YUx34yBvOZhV5ZV3s/UbjPtlZxEDreN79xU46XbPTT5MPsLO7p3tT2Fma6Ev7RCDUAxkzl/CVU22duWy0W1Aoj1Ncv53qUAyNNRZTdyyDs6ZYe9RfGjtH6zMWD1D2x1DEq0W5Lb++T9F2MVboRdB9LmBWFatQeY86WHneCGI1Sy1L+xsWGSFQeU9ETyYbWxE0u36AbXv9E9iqR5xkorIOfrs6Vmz4fyjJ0M22fUSzaoF2DQjaBkNbjdZeM0oBKFcU7RmtqmFhyxTdWZKXxBHrYNvbz2SdXNKJpVl2wZavH8bmfuK3vrB3L4mVffkD", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [#"Task " = _t, #"Start Time " = _t, #"End Time " = _t, #"Duration " = _t, #"Start Day" = _t]),
#"Added Index" = Table.AddIndexColumn(Source, "Index", 1, 1, Int64.Type),
#"Changed Type" = Table.TransformColumnTypes(#"Added Index",{{"Task ", type text}, {"Start Time ", type time}, {"End Time ", type time}, {"Duration ", type time}, {"Start Day", type text}}),
#"Inserted Time Subtraction" = Table.AddColumn(#"Changed Type", "Subtraction", each [#"End Time "] - [#"Start Time "], type duration),
#"Added Custom" = Table.AddColumn(#"Inserted Time Subtraction", "Custom", each let x = Duration.TotalMinutes([Subtraction]),
y = if x<0 then x*-1 else x in y),
#"Added Custom1" = Table.AddColumn(#"Added Custom", "Custom.1", each List.Times([#"Start Time "],[Custom],#duration(0,0,1,0))),
#"Expanded Custom.1" = Table.ExpandListColumn(#"Added Custom1", "Custom.1"),
#"Changed Type1" = Table.TransformColumnTypes(#"Expanded Custom.1",{{"Custom.1", type time}}),
#"Inserted Hour" = Table.AddColumn(#"Changed Type1", "Hour", each Time.Hour([Custom.1]), Int64.Type),
#"Grouped Rows" = Table.Group(#"Inserted Hour", {"Index", "Hour"}, {{"min", each List.Min([Custom.1]), type nullable time}, {"max", each List.Max([Custom.1]), type nullable time}}),
#"Added Custom2" = Table.AddColumn(#"Grouped Rows", "Custom", each Duration.TotalMinutes([max] - [min])+1),
#"Merged Queries" = Table.NestedJoin(#"Added Index", {"Index"}, #"Added Custom2", {"Index"}, "Added Custom2", JoinKind.LeftOuter),
#"Expanded Added Custom2" = Table.ExpandTableColumn(#"Merged Queries", "Added Custom2", {"Hour", "Custom"}, {"Hour", "Custom"}),
#"Removed Other Columns" = Table.SelectColumns(#"Expanded Added Custom2",{"Task ", "Hour", "Custom", "Start Day"}),
#"Renamed Columns" = Table.RenameColumns(#"Removed Other Columns",{{"Custom", "MinsInHours"}}),
#"Changed Type2" = Table.TransformColumnTypes(#"Renamed Columns",{{"MinsInHours", Int64.Type}})
in
#"Changed Type2"
Edit
The same code will work with whatever row gets added
From here
To
I need some help. My data set looks currently like this:
Date Ticket (1/0) Week number
01.07.2020 0 1
01.07.2020 1 1
01.07.2020 1 1
01.07.2020 0 1
15.07.2020 0 2
15.07.2020 0 2
15.07.2020 0 2
01.08.2020 1 3
01.08.2020 1 3
01.08.2020 0 3
01.08.2020 0 3
01.08.2020 1 3
The end result that I need should be something like this:
Date 01.07.2020 15.07.2020 01.08.2020
Development of tickets 2 -2 1
I need the end matrix to sum the tickets in that week and substract the tickets of the previous week from it. How do I achieve that? How should the measure look like?
Thanks for the help!
Let your table name is - your_table_name
Now create a new table new_table_name using this below code-
let
Source = your_table_name,
#"Replaced Value" = Table.ReplaceValue(#"Source",".","-",Replacer.ReplaceText,{"Date"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Replaced Value",{{"Date", type date}}),
#"Grouped Rows" = Table.Group(#"Changed Type1", {"Date", "Week number"}, {{"sum_tickets", each List.Sum([#"Ticket (1/0)"]), type nullable number}}),
#"Added Custom" = Table.AddColumn(#"Grouped Rows", "Custom", each [Week number] + 1),
#"Merged Queries" = Table.NestedJoin(#"Added Custom", {"Week number"}, #"Added Custom", {"Custom"}, "Added Custom", JoinKind.LeftOuter),
#"Expanded Added Custom" = Table.ExpandTableColumn(#"Merged Queries", "Added Custom", {"sum_tickets"}, {"Added Custom.sum_tickets"}),
#"Sorted Rows" = Table.Sort(#"Expanded Added Custom",{{"Week number", Order.Ascending}}),
#"Added Custom1" = Table.AddColumn(#"Sorted Rows", "Final_Total", each [sum_tickets] - [Added Custom.sum_tickets]),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom1",{"sum_tickets", "Custom", "Added Custom.sum_tickets"})
in
#"Removed Columns"
This is the table output-
Now add a matrix visual and add Date to Column field and Final_total to the Values field. The output will be as below-
In Power BI, I have a table looks like:
Customer; Amount Paid; Pay CCY; Amount Received; Received CCY
A 10 USD -20 GBP
B 50 CAD -30 USD
C 100 GBP -50 CAD
I'd like to convert table to:
Customer Amount CCY
A 10 USD
B 50 CAD
C 100 GBP
A -20 GBP
B -30 USD
C -50 CAD
Is there an easy way?
In the Query Editor, select the amount columns and click Unpivot Columns under the Transform tab.
The result should look like this:
Then you can define a custom column to pick which current to use either based on the Attribute column or the Value column. Then remove the extra columns.
The whole query (pasted from the Advanced Editor) looks something like this:
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WclTSUTI0ABKhwS5AUtcIxHZ3ClCK1YlWcgKyTUECzo5gSWOYQpCkM1gnTDlQFq4yNhYA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Customer = _t, #"Amount Paid" = _t, #"Pay CCY" = _t, #"Amount Received" = _t, #"Recieved CCY" = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Customer", type text}, {"Amount Paid", Int64.Type}, {"Pay CCY", type text}, {"Amount Received", Int64.Type}, {"Recieved CCY", type text}}),
#"Unpivoted Columns" = Table.UnpivotOtherColumns(#"Changed Type", {"Customer", "Pay CCY", "Recieved CCY"}, "Attribute", "Amount"),
#"Sorted Rows" = Table.Sort(#"Unpivoted Columns",{{"Attribute", Order.Ascending}, {"Customer", Order.Ascending}}),
#"Added Custom" = Table.AddColumn(#"Sorted Rows", "CCY", each if [Amount] > 0 then [Pay CCY] else [Recieved CCY], type text),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"Pay CCY", "Recieved CCY", "Attribute"})
in
#"Removed Columns"
As said in the comment one could just append the tables. I started with this example
I just appended the table to itself, here is the M -Code
let
Source = Excel.CurrentWorkbook(){[Name="tblData"]}[Content],
tblStart1 = Table.TransformColumnTypes(Source,{{"Customer", type text}, {"Amount Paid", Int64.Type}, {"Pay CCY", type text}, {"Amount Received", Int64.Type}, {"Received CCY", type text}}),
removeColumns1 = Table.SelectColumns(tblStart1,{"Customer", "Amount Paid", "Pay CCY"}),
tblLeft = Table.RenameColumns(removeColumns1,{{"Amount Paid", "Amount"}, {"Pay CCY", "CCY"}}),
tblStart2 = tblStart1,
removeColumns = Table.SelectColumns(tblStart2,{"Customer", "Amount Received", "Received CCY"}),
tblRight = Table.RenameColumns(removeColumns,{{"Amount Received", "Amount"}, {"Received CCY", "CCY"}}),
tblCombine = Table.Combine({tblLeft,tblRight})
in
tblCombine
Result is
This is how my table looks like in Power Query:
For each combination of date and Customer No (No), I need to calculate the sum of Value for the last 365 days.
I need this in Power Query, I know I could do it with DAX.
Are you looking for a 365 day total as of each and every date in the table? If so, then this seems to work
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Date", type date}, {"No", Int64.Type}, {"Value", Int64.Type}}),
#"Added Custom" = Table.AddColumn(#"Changed Type" ,"RunningTotal",(i)=>List.Sum(Table.SelectRows(#"Changed Type" , each [No]=i[No] and [Date]>Date.AddDays(i[Date],-365) and [Date]<=i[Date] ) [Value]), type number )
in #"Added Custom"
Or, 365 days before a specific date like 1980/12/31?
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
MaxDate = #date(1980,12,31),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Date", type date}, {"No", Int64.Type}, {"Value", Int64.Type}}),
#"Filtered Rows" = Table.SelectRows(#"Changed Type", each [Date] <= MaxDate and [Date] > Date.AddDays(MaxDate,-365)),
#"Grouped Rows" = Table.Group(#"Filtered Rows", {"No"}, {{"Total", each List.Sum([Value]), type number}})
in #"Grouped Rows"