DAX formula providing the previous value of a variable, sorted by a different variable - powerbi

I have two tables, Table1 and Table2, containing the following information:
Table1: Sales
Date Firm A Firm B Firm C
30-05-2022 100 200 300
29-05-2022
28-05-2022
27-05-2022 130 230 330
26-05-2022 140 240 340
25-05-2022 150 250 350
and
Table2: Dates
Relative day Date
1 30-05-2022
2 27-05-2022
3 26-05-2022
4 25-05-2022
In my Power BI (PBI) desktop a slicer, allowing the user to select from a range of Relative days (i.e. number of business days from today's date), is present.
What I want is to create a new measure, Sales lag, that contains the lagged value of sales for the individual firm, and for which the lagged value is based on the Relative day variable e.g.:
For the slicer set according to Relative day=1
Sales Sales lag
Firm A 100 130
Firm B 200 230
Firm C 300 330
Please note that I (think I) need the measure to be based on the relative day variable, as the Date variable does not take into account business days.
I previously used a measure that I think was similar to:
Sales lag =calculate(sum(Table1[Sales],dateadd('Table2'[Date],-1,day))
While this measure provided the correct results most of the time, it did not in the presence of weekends.
Thank you

I used some sample data structured slightly differently than you provide and took a stab at providing you with a solution. Find the sample data I used below and the Sales lag measure in the Solution Measure section.
Table1
Date
Firm
Sales
30-05-2022
A
100
29-05-2022
A
110
28-05-2022
A
120
27-05-2022
A
130
26-05-2022
A
140
25-05-2022
A
150
30-05-2022
B
200
29-05-2022
B
210
28-05-2022
B
220
27-05-2022
B
230
26-05-2022
B
240
25-05-2022
B
250
30-05-2022
C
300
29-05-2022
C
310
28-05-2022
C
320
27-05-2022
C
330
26-05-2022
C
340
25-05-2022
C
350
Table2
Relative day
Date
1
30-05-2022
2
27-05-2022
3
26-05-2022
4
25-05-2022
Solution Measure
Sales lag =
VAR sel = SELECTEDVALUE(Table2[Relative day])
VAR dat = CALCULATE(MAX(Table2[Date]), Table2[Relative day] = sel + 1)
RETURN
IF(
ISBLANK(sel),
"",
CALCULATE(
MAX(Table1[Sales]),
ALL(Table2[Relative day]),
Table1[Date] = dat
)
)
Sample Result

Related

How to compare values by different dates in PowerBI

My problem is related with PowerBI report
It is example table, Real table contains 10000+ results
user
salary
date
1
123
14-10-2022
2
455
11-10-2022
3
333
13-10-2022
4
222
12-10-2022
5
111
10-10-2022
desired output:
user
salary
date
salary (date-1 day)
salary (date-3 days)
1
123
14-10-2022
333
455
2
455
11-10-2022
111
3
333
13-10-2022
222
111
4
222
12-10-2022
455
5
111
10-10-2022
How can I achieve it in PBI ?
I tried to merge tables but the dashboard was very slow after try like that.
I would do this in DAX, not Power Query.
Add a date dimension (search on this if you aren’t familiar with date dimensions), then create these DAX measures.
Salary (date-1 day) = CALCULATE( SUM(TABLE[salary]), DATEADD(DateDim[DateKey],-1,day) )
Salary (date-3 day) = CALCULATE( SUM(TABLE[salary]), DATEADD(DateDim[DateKey],-3,day) )

Latest values by category based on a selected date

First, as I am a French guy, I want to apologise in advance for my poor English!
Despite my searches since few days, I cannot find the correct measure to solve my problem.
I think I am close to the solution, but I really need help to achieve this job!
Here is my need:
I have a dataset with a date table and a "Position" (i.e. "stock") table, which is my fact table, with date column.
Classic relationship between these 2 tables. Many Dates in "Position" table / 1 date un "Dates" table.
My "Dates" table has a one date per day (Column "AsOf")
My "Deals" table looks like this:
Id
DealId
AsOfDate
Notional
10000
1
9/1/2022
2000000
10001
1
9/1/2022
3000000
10002
1
9/1/2022
1818147
10010
4
5/31/2022
2000000
10011
4
5/31/2022
997500
10012
4
5/31/2022
1500000
10013
4
5/31/2022
1127820
10014
5
7/27/2022
140000
10015
5
7/27/2022
210000
10016
5
7/27/2022
500000
10017
5
7/27/2022
750000
10018
5
7/27/2022
625000
10019
1
8/31/2022
2000000
10020
1
8/31/2022
3000000
10021
1
8/31/2022
1801257
10022
1
8/31/2022
96976
10023
1
8/31/2022
1193365
10024
1
8/31/2022
67883
Based on a selected date (slicer with all dates from "Dates" table), I would like to calculate the sum of Last Notional for each "Deal" (column "DealId").
So, I must identify, for each Deal, the last "Asof Date" before or equal to the selected date and sum all matching rows.
Examples:
If selected date is 9/1/2022, I will see all rows, except rows asof date = 8/31/2022 for deal 1 (as the last date for this deal is 9/1/2022).
So, I expect to see:
DealId Sum of Notional
1 6 818 147
4 5 625 320
5 2 225 000
Grand Total 14 668 467
If I select 8/31/2022, total for Deal 1 changes (as we now take rows of 8/31 instead of 1/9):
DealId Sum of Notional
1 8 159 481
4 5 625 320
5 2 225 000
Grand Total 16 009 800
If I select 7/29, only deals 4 and 5 are active on this date, so the results should be:
DealId Sum of Notional
4 5 625 320
5 2 225 000
Grand Total 7 850 320
I think I found a solution for the rows, but my total is wrong (only notionals of the selected date are totalized).
I also think my measure is incorrect if I try to display the notional amounts aggregated by Rating (other column in my table) instead of deal.
Here is my measure:
Last Notional =
VAR SelectedAsOf =
SELECTEDVALUE ( Dates[AsOf] )
VAR LastAsofPerDeal =
CALCULATE (
MAX ( Deals[AsOf Date] ),
FILTER ( ALLEXCEPT ( Deals, Deals[DealId] ), Deals[AsOf Date] <= SelectedAsOf )
)
RETURN
CALCULATE (
SUM ( Deals[Notional] ),
FILTER (
ALLEXCEPT ( Deals, Deals[DealId]),
LastAsofPerDeal = Deals[AsOf Date]
)
)
I hope it is clear for you, and you will be able to find a solution for this.
Thanks in advance.
Antoine
Make sure you have no relationship between your calendar table and deals table like so.
Create a slicer with your dates table and create a table visual with deal id. Then add a measure to the table as follows:
Sum of Notional =
VAR slicer = SELECTEDVALUE(Dates[Date])
VAR tbl = FILTER(Deals,Deals[AsOfDate] <= slicer)
VAR maxBalanceDate = CALCULATE(MAX(Deals[AsOfDate]),tbl)
RETURN
CALCULATE(
SUM(Deals[Notional]),
Deals[AsOfDate] = maxBalanceDate
)

How to get a percentage of grouped values over a period of time (at the hour scale) in DAX?

I have a dataset containing the duration (in minutes) of occupancy events over a period of 1 hour in my rooms:
# room date duration
--- ---- ------------------- --------
0 A1 2022-01-01 08:00:00 30
1 A1 2022-01-01 10:00:00 5
2 A1 2022-01-01 16:00:00 30
3 A1 2022-01-02 10:00:00 60
4 A1 2022-01-02 16:00:00 60
...
My date column is linked to a date table in which I have:
# datetime year month monthName day dayOfWeek dayName hour
--- ------------------- ---- ----- --------- --- --------- -------- ----
...
k 2022-01-01 08:00:00 2022 1 January 1 5 Saturday 8
k+1 2022-01-01 09:00:00 2022 1 January 1 5 Saturday 9
...
n 2022-03-01 22:00:00 2022 3 March 1 1 Tuesday 22
I am trying to retrieve the following percentage: duration/timeperiod through a measure. The idea behind using a measure is :
Being able to use a time slicer and see my percentage being updated
Using, for example, a bar chart with my date hierarchy, and being able to see a percentage in my different level of hierarchy (datetime -> year -> month -> dayOfWeek -> hour)
Attempt
My idea was to create a first measure that would return the number of minutes between the first and the last date currently chosen. Here is what I came up with:
Diff minutes = DATEDIFF(
FIRSTDATE( 'date'[date] ),
LASTDATE( 'date'[date] ),
MINUTE
)
The idea was then to create a second measure that would divide the SUM of the durations by the Diff minutes' measure:
My rate = DIVIDE(
SUM( 'table'[duration] ),
[Diff minutes]
)
I currently face a few issues:
The slicer is set to (2022-01-02 --> 2022-01-03) and if I check in a matrix, I have datetime between 2022-01-02 0:00:00 and 2022-01-03 23:00:00, but my measure returns 1440 which is the number of minutes in a day but not in my selected time period
The percentage is also wrong unfortunately. Let's take the example that I highlighted in the capture. There are 2 values for the 10h slot, 5min and 60min. But the percentage shows 4.51% instead of 54.2%. It actually is the result of 65/1440, 1440 being the total of minutes for my whole time period, not my 10h slot.
Examples
1- Let's say I have a slicer over a period of 2 days (2022-01-01 --> 2022-01-02) and my dataset is the one provided before:
I would have a total duration of 185 minutes (30+5+30+60+60)
My time period would be 2 days = 48h = 2880 minutes
The displayed ratio would be: 6.4% (185/2880)
2- With the same slicer, a matrix with hours and percentage would give me:
hour rate
---- -----
0 0.0%
1 0.0%
...
8 25.0% <--- 30 minutes on the 1st of January and 0 minutes on the 2nd
9 0.0% <--- (5+0)/120
10 54.2% <--- (5+60)/120
...
16 75.0% <--- (30+60)/120
Constraints
The example I provided only has 1 room. In practice, there are n rooms and I would like my measure to return the percentage as the mean of all my rooms.
Would it be possible ? Have I chosen the right method ?
The DateDiff function you have created should work, I have tested it on a report and when I select some dates, it gives me the difference between the first and last selected dates.
Make sure your slicer is interacting with the measure.
In the meantime, I think I found a simpler and easier way to do it.
First, I added a new column to my date table, that seems dubious but is actually helpful:
minutes = 60
This allows me to get rid of the DATEDIFF function. My rate measure now looks like this:
My rate = DIVIDE(
SUM( table[duration] ),
[Number of minutes],
0
)
Here, I use the measure Number of minutes which is simply a SUM of the values in the minutes column. In order to provide accurate results when I have multiple rooms selected, I multiplied the number of minutes by the number of rooms:
Number of minutes = COUNTROWS( rooms ) * SUM( 'date'[minutes] )
This now works perfectly with my date hierarchy!

Power Pivot - calculating distinctcount per week (rather than per day)

I am having problems with a distinctcount calculated by week. I have the pivot table below. I want to calculate the distinct number of vendors that have sold more than $2400 per week.
I have the following data table "sales" (only the first rows, but it has several vendors and other weeks as well):
sales day sales week vendor ID Total Sales
02.11.2020 45 vendor 1 405
03.11.2020 45 vendor 1 464
04.11.2020 45 vendor 1 466
05.11.2020 45 vendor 1 358
06.11.2020 45 vendor 1 420
07.11.2020 45 vendor 1 343
I have tried to calculate it as such:
= [vendor] =distinctcount('Sales'[vendor ID])
= [Total_sales] = sum('Sales'[Total Sales])
= [# vendors - 2400] =calculate([vendor],filter('Sales',[Total_sales]>2400))
I know that this calculation considers the sales per day, not per week. so, if instead of using $2400 I used $300, for instance, then both vendors would be marked, since in at least one day, the sales of both are higher than $300. But I only want to consider the sales in a weekly basis.
What I expect (check pivot table below): Vendor 2 would be marked (sales = 2456), but not vendor 1 (sales = 1341), i.e., total number of vendors = 1. However, none of the vendors are being counted, since no daily sales are higher then $2400
Row Labels # Vendors (distinct) total sales
Store A 3797
week 45 3797
Vendor 1 1341
02.11.2020 348
04.11.2020 202
05.11.2020 335
06.11.2020 308
07.11.2020 148
Vendor 2 2456
02.11.2020 405
03.11.2020 464
04.11.2020 466
05.11.2020 358
06.11.2020 420
07.11.2020 343
I also tried to create a column of sales in which I removed the day filter, like this:
=calculate([total_sales],ALL('sales'[sales day]))
and then recalculated the [# vendors - 2400], but it still gets me the same result as above.
The question is: how do I get to consider the total sales value per week (and not per day) for the distinctcount. Thank you for the help!
Do you have a Date calendar in your file? if no try to make one, then have a relationship from date to sales day (assuming this has your dates). That way you should be able to summarize by any date grouping eg, Month, Day, Week, Quarter etc...Or you can try parsing the other date field and add new columns to your table = weeknum(Tablename[sales day])

How do you rank based on a measure referencing two tables in a star schema?

I have a star schema data model. DimDate, DimBranchName, BranchActual, BranchBudget.
I have measures to calculate the YTD variance to Budget by Branch called QVar. Qvar takes the counts from BranchActual and compares it BranchBudget between two dates. The visual is controlled by DimBranchName and DimDate.
Current Result:
BranchName YTDActual YTDBudget QVar
A 100 150 (33%)
B 200 200 0.0%
C 25 15 66%
I want a measure to be able to rank DimBranchName[BranchName] by QVar that will interact with the filters I have in place.
Desired result:
BranchName YTDActual YTDBudget QVar Rank
A 100 150 (33%) 3
B 200 200 0.0% 2
C 25 15 66% 1
What I've tried so far is
R Rank of Actual v Goal =
var V = [QVar]
RETURN
RANKX(ALLSELECTED('BranchActual'),CALCULATE(V),,ASC,Dense)
What I get is all 1's
BranchName YTDActual YTDBudget QVar Rank
A 100 150 (33%) 1
B 200 200 0.0% 1
C 25 15 66% 1
Thanks!
When you declare a variable it is computed once and treated as a constant through the rest of your DAX code, so CALCULATE(V) is simply whatever V was when you declared the variable.
This might be closer to what you want:
R Rank of Actual v Goal =
RANKX ( ALLSELECTED ( DimBranchName[BranchName] ), [QVar],, ASC, DENSE )
This way [QVar] is called within the filter context of the BranchName instead of being a constant. (Note that referencing a measure within another measure implicitly wraps it in CALCULATE so you don't need that again.)