Power Bi DAX: Show data from 6 months past start date - powerbi

i have been having trouble trying to figure out how to show my data past a date that is 6 months past the start date.
I need to show the values that are after the 6 months past the start date.
Each date is different for each person
i have the formula as a calculated column for the 6 months:
+6m = DATEADD('Employee List'[Emp. Dates].[Date], +6, MONTH)
A measure will not work because i cannot apply it to my table as it comes up with an error.
How do i get it to work?
Should i scrap the +6m column for a new formula?

Basic measure:
Total Sales = SUM(Sales[Total Sales])
As long as you do not provide sample data, it is just guessing what you want. It might be it:
YourMeasure =
CALCULATE (
[Total Sales],
DATEADD (
'Employee List'[Emp. Dates].[Date] -- it is better to use here 'Calendar'[Date]
-6,
MONTH
)
)
update
This will give you a good start.
Sample data:
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMjIwMtA1MAQiJR0lQ6VYHZiQEaaQMaaQCaaQKaaQGaaQOaaQBaaQJYaQoQGmEKbrDdFdb4jpR0NkP8YCAA==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type text) meta [Serialized.Text = true]) in type table [Date = _t, Amount = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Date", type date}, {"Amount", Int64.Type}})
in
#"Changed Type"
Measure =
var MinDate = CALCULATE( MIN(T[Date]), REMOVEFILTERS(T[Date]) )
var SixMonthAfter = CALCULATE( DATEADD( T[Date], 6 , MONTH ), T[Date] = MinDate )
return
CALCULATE( SUM( T[Amount] ), FILTER( T, T[Date] > SixMonthAfter ) )

Related

Create an average table excluding some values

I have a table with this structure:
Date
DeviceID
Value
01/01/2022
SensorA
1200
01/01/2022
SensorB
1300
01/01/2022
SensorC
900
02/01/2022
SensorA
500
02/01/2022
SensorB
50
02/01/2022
SensorC
39
I'm interesting in create a new table that have the average by day of all sensors values but excluding the values which are lower than the average of all sensors by day.
For example for 01/01/2022 the average of all sensors values is:
(1200+1300+900) / 3 = 1133.3
We then calculate the average sensor value for the day, excluding SensorC because its value is below 1133.3:
(1200+1300) / 2 = 1250
The final table have to looks like this:
Date
Value
01/01/2022
1250
02/01/2022
500
Is it possible? Hope you can help me
Thanks in advance!
This does exactly what you are asking for:
Avg Excl =
VAR _avg = AVERAGE ( 'Table'[Value] )
RETURN
CALCULATE (
AVERAGE ( 'Table'[Value] ) ,
'Table'[Value] > _avg
)
Result:
If you want to persist a DAX table to your model, you just use this code together with SUMMARIZE:
New_Table =
SUMMARIZE (
'Table' ,
'Table'[Date] ,
"Value",
VAR _avg = AVERAGE ( 'Table'[Value] )
RETURN
CALCULATE (
AVERAGE ( 'Table'[Value] ) ,
'Table'[Value] > _avg
)
)
Result:
For good measure, here is some Power Query code to achieve the same result. Usually this is best practice due to compression efficiency and such in Power BI. As a bonus, it also makes working with the pbix file smoother since you don't have to wait for the table to recalculate all the time when you add/remove/edit DAX components.
This solution is your best bet if this his how you actually want your table to look, since you can get rid of the original table in the model altogether and not have it in the model as a dependency. You can paste this into a blank query:
let
Source = Table.FromRecords({
[Date="2022-01-01", DeviceID="SensorA",Value=1200],
[Date="2022-01-01", DeviceID="SensorB",Value=1300],
[Date="2022-01-01", DeviceID="SensorC",Value=900],
[Date="2022-01-02", DeviceID="SensorA",Value=500],
[Date="2022-01-02", DeviceID="SensorB",Value=50],
[Date="2022-01-02", DeviceID="SensorC",Value=39]
}),
#"Changed Type" = Table.TransformColumnTypes(Source,{
{"Date", type date},
{"DeviceID", type text},
{"Value", Int64.Type}
}),
#"Grouped Rows" = Table.Group(#"Changed Type", {"Date"}, {
{"Avg", each List.Average([Value]), type nullable number},
{"Data", each _, type table [Date=nullable date, DeviceID=nullable text, Value=nullable number]}
}),
#"Expanded Data" = Table.ExpandTableColumn(#"Grouped Rows", "Data", {"Value"}, {"Data.Value"}),
#"Added Custom" = Table.AddColumn(#"Expanded Data", "Custom", each if [Data.Value] > [Avg] then [Data.Value] else null),
#"Grouped Rows1" = Table.Group(#"Added Custom", {"Date"}, {{"Avg Value", each List.Average([Custom]), type nullable number}})
in
#"Grouped Rows1"
Since you are using the Device ID column in the table, it shows all of them separately. Can you remove the DeviceID column and try the value column as average?

Power BI calculate workdays in month

I have a lot to learn of Power BI and I am currently stuck with a column I need to add in my Calendar table.
I have to calculate a workday column that should flag each day of the month with it's workday number (from 1 to the maximum number of working days for that month).
I was able to find a solution online with RANKX (I have a column, NonWorkday that flags with 1 for all days that are either weekends or holidays) but it's not complete:
Workday =
VAR CurrentMonth = Calendar[MonthYear]
VAR MonthTable = FILTER( ALL( Calendar ), Calendar[NonWorkDay] = 0 && Calendar[MonthYear] = CurrentMonth )
RETURN
IF( Calendar[NonWorkDay] = 1, BLANK(), RANKX(MonthTable, CALCULATE(AVERAGE(Calendar[DayofMonth])), ,ASC))
What I'm missing is that, for weekends and holidays I don't want blank, I want it to have the same workday number as the previous workday and if the month starts with a non-working day, that will be 0. An example image below:
It would be great if anyone can help me with a solution or point me in the right direction, either DAX or M query.
Thank you!
LE: Adding MVE code, as per #Marco_CH request:
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("bdJBDoMwDATAv+RciXgTSPIW1P9/oxTbar34wGUQCWvveRbZZEMFyqvI9dTyfp0FGbYMe4b7D+v94otHRNw4IrYbZzxTcWUoNVWJp3ZVRN1VW9RDtUcdqnu8zfRIlZJN1Rl1qS6aly2hEuscQelEJwnamXPLmQKKTg68OR0daHeiswNlFB0eKKToREAbNG41Z05pA9zwbBYiwtqKZ7N6xG5txf8PdGtrgiN+vltb8SzQiji8rUg6IfGq6W3NtKVKsZa3FUmr5CAW7yuSVgmls57Iiv/h9ak589a6NxZZqyijM4X0snHK4Y2Nh0xvbMqc8prg+wM=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Date = _t, NonWorkDay = _t, WantedWorkday = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Date", type date}, {"NonWorkDay", Int64.Type}, {"WantedWorkday", Int64.Type}})
in
#"Changed Type"
LE2: My final calculation based on the answered provided by #msta42a:
WD =
var day ='Calendar'[Date]
VAR CurrentMonth = Calendar[MonthYear]
return
CALCULATE( COUNTROWS('Calendar'), FILTER('Calendar', Calendar[MonthYear] = CurrentMonth && 'Calendar'[Date] <= day && 'Calendar'[NonWorkDay] <> 1)) +0
Results:
You can calculate this like "running count/total" here my example (in your code you should add a clause for month/year)
Workday =
var day ='Calend'[Date]
return
CALCULATE( COUNTROWS('Calend'), FILTER('Calend', 'Calend'[Date] <= day && 'Calend'[Weekend]="wd" && Calend[Nonworking] <> 0)) +0

How to calculate frequency received data from time column in Power BI?

I have a table with received time like the below:
As you see, the frequency of received data in some rows is different and they are 1000ms, 1001ms, 998ms.
How can I calculate the average frequency of received time in ms?
I suggest using Power Query to
add a column that is the original date_time column offset by 1
Then add another column showing the difference between current row and previous row
This method, at least in M Code, is faster than using an Index column to refer to previous row
Then you can do your mathematical analyses.
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("dc27DcAgDAXAVRA1An9iO2EVxP5rgEQZXn3FjZGjsTUh4cRdqctTwy3P8heD4lv8KgHl3RJX+dCjBIXRo3JkLg==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [date_time = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"date_time", type datetime}}),
//add column containing previous rows data
//usually faster than using and INDEX column
prevList = {null} & List.RemoveLastN(#"Changed Type"[date_time]),
tbl1 = Table.FromColumns(
{#"Changed Type"[date_time],prevList},
{"date_time","Prev Row"}
),
#"Added Custom" = Table.AddColumn(tbl1, "Difference", each /*if [Prev Row] = null then 0
else*/ Duration.TotalSeconds([date_time] - [Prev Row])),
#"Changed Type1" = Table.TransformColumnTypes(#"Added Custom",{
{"date_time", type datetime}, {"Prev Row", type datetime}, {"Difference", type number}})
in
#"Changed Type1"
In PowerQuery add an Index column to your data so that you can address singe rows. Then with DAX add a calulated column to the table:
Milliseconds =
VAR NextIndex = 'Table'[Index] + 1
VAR MaxIndex = MAX(Table[Index])
VAR Difference =
IF(
'Table'[Index] = MaxIndex,
BLANK(),
'Table'[date_time] -
CALCULATE(
VALUES('Table'[date_time]),
Filter(
ALL('Table'),
'Table'[Index] = NextIndex
)
)
)
RETURN
CONVERT(ABS(Difference * 3600 * 24 * 1000), INTEGER)
Now you are looking for AVERAGE( Milliseconds ).
Note: Things would have been easier if you provided copyable data instead of a screenshot.

Table with all dates between last sales day and defined N periods

How to get Dates for N last full months. I want the last month to be determined by Sales amount.
This is the whole table for the example.
The expected result is a calculated table of Date column from 2020-05-01 to 2020-07-31. Looks like this:
Date
2020-05-01
2020-05-02
2020-05-03
…
2020-07-29
2020-07-30
2020-07-31
What have I tried? First, a measure to get the last date with sales:
MaxDate =
CALCULATE(
EOMONTH( MAX( T[Date] ), 0),
ALL( T ),
T[Amount] > 0
)
And the calculated table:
T_Range =
var a = [MaxDate]
var b = DATESINPERIOD( T[Date] , a, -3, MONTH )
return
b
But it returns only 3 days, not the whole range from 2020-05-01 to 2020-07-31.
The table to reproduce the problem:
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("ZcrLCQAgDATRXnJWSNZ/LWL/bShIQFyY02PmFCg0qp0kiMkKTmBKTJmpROCjyldj6pceGb+YkhgJXNYG", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type text) meta [Serialized.Text = true]) in type table [Date = _t, Amount = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Date", type date}, {"Amount", Int64.Type}})
in
#"Changed Type"
Please check if this helps -
Created a new column with 'Max date' measure you provided.
Then crated min date column with below DAX.
Min Date = EDATE([MaxDate],-3)+1
Created new table using below.
T_Range = CALENDAR(MAX(T[Min Date]),MAX(T[Max Date]))

PowerBi timeseries duration

In PowerBI, I have a simple table with 3 columns:
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("TYzBCcAwDAN38dugyk5bdxaT/deICzXN77hDyhSKCkHYwafwbJyaYiUc9I4XaH/1MgHeXQO+bcf7ux0XW3x5Lg==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type text) meta [Serialized.Text = true]) in type table [id = _t, start = _t, end = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"id", Int64.Type}, {"start", type date}, {"end", type date}})
in
#"Changed Type"
From which I can create the following visual
My challenge is to calculate the total duration in days of the times series based on filter selected above. Any help would be appreciated.
I have tried the following DAX formula but it gives me crazy results as shown above.
YTDDuration =
var start_Date=FIRSTDATE(ALLSELECTED('CALENDAR'[Date]))
var end_Date=LASTDATE(ALLSELECTED('CALENDAR'[Date]))
var current_Start=MAX(Table2[start])
var current_end=MAX(Table2[end])
var bigif=IF(current_end>start_Date&&current_Start<end_Date,DATEDIFF(MAX(start_Date,current_Start),MIN(end_Date,current_end),DAY),0)
RETURN
CALCULATE(SUMX(Table2, bigif),FILTER(ALL(Table2), Table2[start] <= max(Table2[end])))
Expected output would be:
The key here is to account for gaps in dates and consolidate overlapping dates.
You can iterate through your calendar table and count the number of days where that day falls into one of the id time periods.
YTDDuration =
var current_Start = CALCULATE(MIN(Table2[start]), ALL(Table2))
var current_end = MAX(Table2[end])
RETURN
SUMX(
FILTER('CALENDAR', 'CALENDAR'[Date] <= current_end),
MAXX(ALL(Table2), IF([Date] > [start] && [Date] <= [end], 1, 0))
)
This starts at the minimal start date and adds 1 for each day where that Date is between start and end for some row in Table2. If none of the rows contains that Date, the max is over just zeros and returns zero. If one or more matches, you get a max of one and we count that day.
YTD Duration by end: