I have a Raw Data table in Power BI where I am trying to count the number of jobs performed in the last hour of each day, preferably using DAX.
A representation of the table can be built in DAX using (the actual table is built from various CSV files in Power Query):
Raw Data = {
( "A", "42784", DATE( 2022, 8, 31 ), 5 ),
( "A", "91783", DATE( 2022, 8, 31 ), 5 ),
( "A", "19845", DATE( 2022, 8, 31 ), 6 ),
( "A", "76165", DATE( 2022, 8, 31 ), 6 ),
( "A", "28253", DATE( 2022, 8, 31 ), 7 ),
( "A", "83294", DATE( 2022, 8, 31 ), 8 ),
( "A", "47431", DATE( 2022, 8, 31 ), 9 ),
( "A", "20025", DATE( 2022, 8, 31 ), 10 ),
( "A", "10564", DATE( 2022, 8, 31 ), 10 ),
( "A", "65463", DATE( 2022, 8, 31 ), 10 ),
( "B", "44750", DATE( 2022, 9, 1 ), 5 ),
( "B", "47302", DATE( 2022, 9, 1 ), 6 ),
( "B", "31759", DATE( 2022, 9, 1 ), 6 ),
( "B", "26638", DATE( 2022, 9, 1 ), 7 ),
( "B", "55076", DATE( 2022, 9, 1 ), 7 ),
( "B", "59205", DATE( 2022, 9, 1 ), 8 ),
( "B", "52319", DATE( 2022, 9, 1 ), 8 )
}
I then have a second table built in DAX which gives me the unique date values (the actual table copies the date column from a date table - which is itself sourced from the raw data)
Dimension = CALENDAR(FIRSTDATE('Raw Data'[Value3]), LASTDATE('Raw Data'[Value3]))
The problem comes when I add a column to try and count how many items were processed in the last hour on each day.
Items are counted by counting the Value 2 column. Hour of the day is shown in the Value 4 column.
So 3 items on 31st August at 10 o'clock, 2 items on 1st September at 8 o'clock.
The DAX I'm using for this is:
LatestUnitsProcessed =
CALCULATE (
DISTINCTCOUNT ( 'Raw Data'[Value2] ),
FILTER (
FILTER ( 'Raw Data', 'Raw Data'[Value3] = 'Dimension'[Date] ),
'Raw Data'[Value4] = MAX('Raw Data'[Value4])
)
)
This correctly returns 3 for 31st August, but leaves 1st September blank. Pretty sure this is because MAX('Raw Data'[Value4]) is ignoring the date and trying to see how many were processed at 10 o'clock on the 1st.
How would I include the data criteria to do this?
This creates a virtual relationship.
LatestUnitsProcessed =
VAR last = CALCULATE(MAX('Raw Data'[Value4]), TREATAS({'Dimension'[Date]} ,'Raw Data'[Value3]))
RETURN
CALCULATE (
DISTINCTCOUNT ( 'Raw Data'[Value2] ),
TREATAS({'Dimension'[Date]} ,'Raw Data'[Value3]),
'Raw Data'[Value4] = last
)
try this with relationship (Dimension --> Value3)...
LatestUnitsProcessed =
VAR _max =
MAX ( 'Raw Data'[Value4] )
RETURN
CALCULATE (
DISTINCTCOUNT ( 'Raw Data'[Value2] ),
ALLEXCEPT ( 'Raw Data', 'Raw Data'[Value3] ),
'Raw Data'[Value4] = _max
)
Sample File
Related
I have a table called Payment_Methods in PBI with the following columns:
timestamp, weekDay, Hour, eventType, SuccessEvents, FailedEvents, addPymntCardInstance.
weekDay is ['Sunday', 'Monday', ..., 'Friday', 'Saturday']
Hour is [0, 1, 2, 3, ..., 21, 22, 23]
I want to create a PymntSuccessRate using the DAX expression below, but the results are always the same all the way down across the column PymntSuccessRate. How can I fix this. Appreciate if you can give me some clue. Thanks.
PymntSuccessRate =
DIVIDE(
SUMX(
FILTER(
GROUPBY(
Payment_Methods,
Payment_Methods[timestamp], Payment_Methods[weekDay], Payment_Methods[Hour]
),
Payment_Methods[eventType] = "Success"
),
SUM( Payment_Methods[addPymntCardInstance] )
),
SUMX(
GROUPBY(
Payment_Methods,
Payment_Methods[timestamp], Payment_Methods[weekDay], Payment_Methods[Hour]
),
SUM( Payment_Methods[addPymntCardInstance] )
)
)
timestamp
weekDay
Hour
SuccessEvents
FailedEvents
SuccessRate
2023-01-20
Friday
20
2
8
0.20
2023-01-20
Friday
19
121
111
0.52
2023-01-17
Tuesday
6
31
8
0.79
2023-01-17
Tuesday
5
19
14
0.57
based on your sample you don't need to use SUMX and GROUPBY (visual will do the grouping), this should be enough (used as a measure, NOT a calculated column):
PymntSuccessRate =
DIVIDE (
CALCULATE (
SUM ( Payment_Methods[addPymntCardInstance] ),
Payment_Methods[eventType] = "Success"
),
SUM ( Payment_Methods[addPymntCardInstance] )
)
I'm trying to find out how to choose first and last date and quantity for each category, here ORDER_LINE_RELEASE_NO.
ORDER_LINE_RELEASE_NO
WANTED_DATE_OLD
WANTED_DATE_NEW
BUY_QTY_DUE_OLD
BUY_QTY_DUE_NEW
49562_1_9
27.01.2022
1
49562_1_9
27.01.2022
27.01.2022
1
2660
50081_1_1
31.01.2022
6
50081_1_1
31.01.2022
31.03.2022
6
6
50081_1_1
31.03.2022
31.03.2022
6
1210
50084_1_1
10.02.2022
1
50084_1_1
10.02.2022
10.03.2022
1
1
50084_1_1
10.03.2022
10.06.2022
1
1
50084_2_1
10.02.2022
60
50084_2_1
10.02.2022
08.04.2022
60
60
52370_1_1
13.05.2022
3000
52370_1_1
13.05.2022
13.05.2022
3000
2000
In this original table I have the same ORDER_LINE_RELEASE_NO in more rows and I would like to "summarize" it like in the second table here:
ORDER_LINE_RELEASE_NO
FIRST_DATE
LAST_DATE
ORIGINAL_QTY
LAST_WANTED_QTY
49562_1_9
27.01.2022
27.01.2022
1
2660
50081_1_1
31.01.2022
31.03.2022
6
1210
50084_1_1
10.02.2022
10.06.2022
1
1
50084_2_1
10.02.2022
08.04.2022
60
60
52370_1_1
13.05.2022
13.05.2022
3000
2000
So basically in the column FIRST_DATE we have the first value from column WANTED_DATE_NEW (for each category), in LAST_DATE the last value from WANTED_DATE_NEW, in ORIGINAL_QTY is the first value from BUY_QTY_DUE_NEW and in LAST_WANTED_QTY we have the last value from BUY_QTY_DUE_NEW.
I tried to use FIRSTNONBLANK and LASTNONBLANK functions, but they only work fot dates, not for all quantity - for example for 52370_1_1 quantity.
My code in creating new table from another in powerBI was:
PURCH_ORD_LINE_UNIQUE =
ADDCOLUMNS (
DISTINCT ( PURCH_ORD_LINE_ARCH[ORDER_LINE_RELEASE_NO] ),
"FIRST_DATE",
CALCULATE (
FIRSTNONBLANK (
PURCH_ORD_LINE_ARCH[WANTED_DATE_NEW],
PURCH_ORD_LINE_ARCH[WANTED_DATE_NEW]
),
ALLEXCEPT ( PURCH_ORD_LINE_ARCH, PURCH_ORD_LINE_ARCH[ORDER_LINE_RELEASE_NO] )
),
"LAST_DATE",
CALCULATE (
LASTNONBLANK (
PURCH_ORD_LINE_ARCH[WANTED_DATE_NEW],
PURCH_ORD_LINE_ARCH[WANTED_DATE_NEW]
),
ALLEXCEPT ( PURCH_ORD_LINE_ARCH, PURCH_ORD_LINE_ARCH[ORDER_LINE_RELEASE_NO] )
),
"ORIGINAL_QTY",
CALCULATE (
FIRSTNONBLANK (
PURCH_ORD_LINE_ARCH[BUY_QTY_DUE_NEW],
PURCH_ORD_LINE_ARCH[BUY_QTY_DUE_NEW]
)
),
"LAST_WANTED_QTY",
CALCULATE (
LASTNONBLANK (
PURCH_ORD_LINE_ARCH[BUY_QTY_DUE_NEW],
PURCH_ORD_LINE_ARCH[BUY_QTY_DUE_NEW]
)
)
)
Sorry if my question is too stupid, I'm quite new to DAX and PowerBI.
Thanks for any answer.
Tomas
here is my solution : (i will share the sample file at the end, so you can easily understand my approach)
First we will add an index column to the table :
#"Added Index" = Table.AddIndexColumn(#"Changed Type", "Index", 1, 1, Int64.Type)
then, we will add grouped index number column :
Group Ranking =
RANKX (
FILTER (
'Table',
EARLIER ( 'Table'[ORDER_LINE_RELEASE_NO ] ) = 'Table'[ORDER_LINE_RELEASE_NO ]
),
'Table'[Index],
,
ASC,
DENSE
)
finally, we create our table :
Modelling --> New Table
Result Table =
ADDCOLUMNS (
SUMMARIZE ( 'Table', 'Table'[ORDER_LINE_RELEASE_NO ] ),
"FIRST_DATE", CALCULATE ( MIN ( 'Table'[WANTED_DATE_OLD ] ) ),
"LAST_DATE", CALCULATE ( MAX ( 'Table'[WANTED_DATE_new ] ) ),
"ORIGINAL_QTY",
VAR _max =
CALCULATE (
MIN ( 'Table'[Group Ranking] ),
ALLEXCEPT ( 'Table', 'Table'[ORDER_LINE_RELEASE_NO ] ),
NOT ( ISBLANK ( 'Table'[BUY_QTY_DUE_OLD ] ) )
)
RETURN
CALCULATE (
FIRSTNONBLANK ( 'Table'[BUY_QTY_DUE_OLD ], 1 ),
ALLEXCEPT ( 'Table', 'Table'[ORDER_LINE_RELEASE_NO ] ),
'Table'[Group Ranking] = _max
),
"LAST_WANTED_QTY",
VAR _max =
CALCULATE (
MAX ( 'Table'[Group Ranking] ),
ALLEXCEPT ( 'Table', 'Table'[ORDER_LINE_RELEASE_NO ] )
)
RETURN
CALCULATE (
SUM ( 'Table'[BUY_QTY_DUE_NEW] ),
ALLEXCEPT ( 'Table', 'Table'[ORDER_LINE_RELEASE_NO ] ),
'Table'[Group Ranking] = _max
)
)
Here is the sample PBix File for you...
I have a Power BI matrix with 3 columns: 2019, 2020, and 2021. Each row is an item number, and each value is a total quantity produced in the corresponding year column.
I am trying to find a way to display the sum of ONLY items that were blank in 2019 and 2020, BUT have a total quantity in the 2021 column. Is there a way to conditionally format this?
Basically, another way of saying the logic is: total sum of all items where 2019 AND 2020 are blank, AND 2021 is not blank.
Try this solution if it helps then mark it as the answer.
Create a calculated column with the following DAX:
Column =
IF (
(
Table[Year] = 2019 || Table[Year] = 2020 ),
IF ( ISBLANK ( Table[Item] ), ( Table[Quant] ) ),
IF ( Table[Year] = 2021, IF ( ISNUMBER ( Table[Item] ), ( Table[Quant] ) ) )
)
Input I used:-
Output where 2019 and 2020 Items are blank and 2021 where Items are not blank:-
You can create the following measure:
Measure =
IF (
CALCULATE(
SUM(Table[Quantity]),
Table[Year] => 2019,
Table[Year] <= 2020,
) > 0,
0,
CALCULATE(
SUM(Table[Quantity]),
Table[Year] = 2021
)
)
And in the table you should filter that visual so it only shows values where this Measure is > 0. However, if your intention is to have this dynamically (i.e. so this still makes sense next year with years 2020, 2021 and 2022), I would recommend this:
Measure =
IF (
CALCULATE(
SUM(Table[Quantity]),
Table[Year] => YEAR(TODAY()) - 2,
Table[Year] <= YEAR(TODAY()) - 1,
) > 0,
0,
CALCULATE(
SUM(Table[Quantity]),
Table[Year] = YEAR(TODAY())
)
)
I need help finding a way to count the number of consecutive months:
For every "ID" (Text Column)
Having the column "Status" either "Missing" or "On hold"
Here is what my table looks like (the last two columns are the output I would like to see):
ID
Year
Month
Date (01-Month-Year)
Status
Consecutive Months "Missing"
Consecutive Months "On Hold"
ID40
2019
6
01/06/2019
Missing
0
-
ID40
2019
7
01/07/2019
Missing
2
-
ID40
2019
8
01/08/2019
Missing
3
-
ID40
2019
11
01/11/2019
Missing
0
-
ID40
2019
12
01/12/2019
Missing
2
-
ID40
2020
9
01/09/2020
Missing
0
-
ID499
2019
1
01/01/2019
On Hold
-
0
ID499
2019
2
01/02/2019
On Hold
-
2
ID499
2019
3
01/03/2019
On Hold
-
3
ID499
2020
9
01/09/2020
On Hold
-
0
ID499
2020
10
01/10/2020
On Hold
-
2
ID499
2020
8
01/08/2020
Missing
0
-
ID499
2020
9
01/09/2020
Missing
2
-
ID499
2020
10
01/10/2020
Missing
3
-
ID499
2020
11
01/11/2020
Missing
4
-
ID499
2020
12
01/12/2020
Missing
5
-
Is there any way to do this besides with merged nested queries in "M"? Unfortunately I have already tried this, but PowerBI has trouble processing the data.
Thanks everyone in advance!
A possible solution is to build a table of the Years and Months since the first Year in the table and remove from it the Year Months that appear in the table. Than compute the difference in months between the current Year Month and the last non existent Year Month.
This is a possible calculated column that uses the EXCEPT function to build the table with the missing Year Months. To ease the computation of the difference in months across the years, it also prepares a YearMonthNumber value with the progressive month number from the first year month
Since in the example table there are separate columns for the Status, I added an IF to split the columns accordingly
I also added a check to return 0 instead of 1, to match the example data
Consecutive Months Missing =
IF (
T[Status] = "Missing",
VAR FirstYear =
MIN ( T[Year] )
VAR CurrentYear = T[Year]
VAR CurrentMonth = T[Month]
VAR CurrentYearMonthNumber = ( CurrentYear - FirstYear ) * 12 + CurrentMonth
VAR YearMonths =
GENERATE (
SELECTCOLUMNS ( GENERATESERIES ( FirstYear, CurrentYear ), "Year", [Value] ),
SELECTCOLUMNS (
GENERATESERIES ( 1, 12, 1 ),
"Month", [Value],
"YearMonthNumber",
( [Year] - FirstYear ) * 12 + [Value]
)
)
VAR CurrentIDAndStatusYearMonths =
CALCULATETABLE (
ADDCOLUMNS (
SUMMARIZE ( T, T[Year], T[Month] ),
"YearMonthNumber",
( T[Year] - FirstYear ) * 12 + T[Month]
),
ALLEXCEPT ( T, T[ID], T[Status] )
)
VAR MissingYearMonths =
EXCEPT ( YearMonths, CurrentIDAndStatusYearMonths )
VAR FirstMissingYearMonthNumber =
MAXX (
FILTER ( MissingYearMonths, [YearMonthNumber] < CurrentYearMonthNumber ),
[YearMonthNumber]
)
VAR Result = CurrentYearMonthNumber - FirstMissingYearMonthNumber
RETURN
IF ( Result = 1, 0, Result )
)
and
Consecutive Months On Hold =
IF (
T[Status] = "On Hold",
VAR FirstYear =
MIN ( T[Year] )
VAR CurrentYear = T[Year]
VAR CurrentMonth = T[Month]
VAR CurrentYearMonthNumber = ( CurrentYear - FirstYear ) * 12 + CurrentMonth
VAR YearMonths =
GENERATE (
SELECTCOLUMNS ( GENERATESERIES ( FirstYear, CurrentYear ), "Year", [Value] ),
SELECTCOLUMNS (
GENERATESERIES ( 1, 12, 1 ),
"Month", [Value],
"YearMonthNumber",
( [Year] - FirstYear ) * 12 + [Value]
)
)
VAR CurrentIDAndStatusYearMonths =
CALCULATETABLE (
ADDCOLUMNS (
SUMMARIZE ( T, T[Year], T[Month] ),
"YearMonthNumber",
( T[Year] - FirstYear ) * 12 + T[Month]
),
ALLEXCEPT ( T, T[ID], T[Status] )
)
VAR MissingYearMonths =
EXCEPT ( YearMonths, CurrentIDAndStatusYearMonths )
VAR FirstMissingYearMonthNumber =
MAXX (
FILTER ( MissingYearMonths, [YearMonthNumber] < CurrentYearMonthNumber ),
[YearMonthNumber]
)
VAR Result = CurrentYearMonthNumber - FirstMissingYearMonthNumber
RETURN
IF ( Result = 1, 0, Result )
)
this is the resulting table put in a table visual
While building a calendar table I came across unexpected hard nut to crack.
How to convert date to the first date of the quarter? Here are some examples:
2019-02-01 > 2019-01-01
2019-03-31 > 2019-01-01
2019-04-02 > 2019-04-01
The function STARTOFQUARTER does not work in my calendar. I do not know why.
Calendar =
GENERATE (
CALENDAR (
DATE ( 2016, 1, 1 ),
DATE ( 2020, 12, 31 )
),
VAR VarDates = [Date]
var YQ_date = STARTOFQUARTER( [Date] ) -- this does not work
RETURN
ROW (
"day" , VarDay,
"YQ_date" , YQ_date
)
)
The only option seems to be adding calculated column to Calendar table. But if it is possible to have it straight, then why not have it straight?
How about as an added column?
Calendar =
ADDCOLUMNS (
CALENDAR ( DATE ( 2016, 1, 1 ), DATE ( 2020, 12, 31 ) ),
"YQ_date", EOMONTH ( [Date], -1 - MOD ( MONTH ( [Date] ) - 1, 3 ) ) + 1
)
For the STARTOFQUARTER function to work, you need the dates that you expect to be returned by the function in your datetable.
So in the provided sample, you need to add the dates 2019-01-01 and 2019-04-01.
Something like this:
When you want to build a calendar table with one DAX expression, you cannot use the STARTOFQUARTER function, because it will not work with an in-memory table.
You could use something like this as a workaround though:
Calendar =
GENERATE (
CALENDAR (
DATE ( 2016; 1; 1 );
DATE ( 2020; 12; 31 )
);
ROW (
"YQ_date"; DATE( Year( [Date] ); ROUNDUP( MONTH ( [Date] ) / 3; 0 ) * 3 - 2; 1)
)
)