What is the PowerBI/DAX query equivalent of this SQL windowed function - powerbi

I have the following Table:
NDayNo Customer Date CallID
0 A 02/09/2018 48451
24 A 26/09/2018 48452
0 B 21/09/2018 48453
4 B 25/09/2018 48454
0 C 17/09/2018 48455
8 C 25/09/2018 48456
9 C 26/09/2018 48457
9 C 26/09/2018 48458
0 D 09/09/2018 48459
The NDayNo. value was worked out using this function in SQL:
COALESCE(DATEDIFF(day,FIRST_VALUE(Date) OVER (PARTITION BY Customer ORDER By Date),Date),0)
NDayNo. = working out the first time the customer contacts in the month (=0) and then how many days until next time they contact.
Im trying to replicate the same logic in PowerBI. Anybody know how I can calculate this as a calculated column/ DAX query?

This should work for you:
NDayNo =
DATEDIFF (
CALCULATE ( MIN ( 'table'[Date] ), ALLEXCEPT ( 'table', 'table'[Customer] ) ),
'table'[Date],
DAY
)
This DAX expression returns for each row the difference in days between the minimum [date] in the whole table (only filtered to the [Customer] in that row) and the [date] in that row.

Related

Moving Annual Total with DAX Power BI

I'm trying to calculate MAT (Moving Annual Total) using DAX, but can't realize exactly what I want.
I have the data as below.
What I'm trying to is calculate the total of treatment for each 12 month, like "Jan 21 - Dec 21" which has 'date' from 2020/1/1 to 2020/12/1. i.e. 'A' appears 4 times in that period, so the result will be like below.
Then I'd like to continue this for each latest 12 months, and finally visualize it like below.
I've read that I should use CALCULATE and DATESPERIOD in DAX, can't calculate exactly though. The following code is the one I tried and failed.
Moving Annual Total = CALCULATE(
COUNTA('2017-2022Q1'[idnum]),
DATESINPERIOD('2017-2022Q1'[mat].[Date], LASTDATE('2017-2022Q1'[mat].[Date]), 12, MONTH))
Could someone kindly give me an advise to realize this?
Thanks.
*This is the sample file.
https://drive.google.com/file/d/1gDNeBe5KiKBqx3cZ7G0SMiSQ23w96NF4/view?usp=sharing
In your dax measure, I recommend you first to create a date table and create a one-to-many relationship with the fact table(your table: '2017-2022Q1') ; then filter the date table in your calculate measure, not the fact table('2017-2022Q1') directly as you did here. You should follow the best practice.
For Example: How to create a date table using dax:
Date =
VAR MinYear = YEAR ( MIN ( '2017-2022Q1'[date] ) )
VAR MaxYear = YEAR ( MAX ( '2017-2022Q1'[date] ) )
RETURN
ADDCOLUMNS (
FILTER (
CALENDARAUTO( ),
AND ( YEAR ( [Date] ) >= MinYear, YEAR ( [Date] ) <= MaxYear )
),
"Calendar Year", "CY " & YEAR ( [Date] ),
"Month Name", FORMAT ( [Date], "mmmm" ),
"Month Number", MONTH ( [Date] )
)
Your final code could be like this:
Moving Annual Total = CALCULATE(
COUNTA('2017-2022Q1'[idnum]),
DATESINPERIOD('Date'[Date], LASTDATE('Date'[Date]), -12, MONTH)
)
if you define the start date using the lastdate() function, then It returns the last date in your filter context. you should also specify the interval as (-12) month to extract all dates within 1 year period.
Hope It helps.

Calculating the cumulative values in Power BI

I have two tables:
user table (contains: user registration data. columns: user_id, create_date)
customer order table (contains: history of orders. columns: user_id, order_date, order_id)
*user and customer aren't the same. when a user registers his first order, he becomes a customer.
For each month of each year, I want the accumulative count of distinct users and the accumulative count of the distinct customers because at last, I want to calculate the ratio of the accumulative count of the distinct customers to the accumulative count of the distinct users for each month.
I don't know how can I calculate the accumulative values and the Ratio that I said, using DAX.
Note that if a customer registers more than one order in a month, I want to count him just once for that month and if he registers a new order in the next months, also I count him in each new month.
Maybe these pictures help you to understand my question better.
-I don't count_of_users and count_of_customers columns in my tables. I should calculate them.
the user table:
user_id
create_date
1
2017-12-03
2
2018-01-01
3
2018-01-01
4
2018-02-04
5
2018-03-10
6
2018-04-07
7
2018-04-08
8
2018-09-12
9
2018-10-02
10
2018-10-02
11
2018-10-09
12
2018-10-11
13
2018-10-12
14
2018-10-12
15
2018-10-20
the customer order table:
user_id
order_date
order_id
1
2018-03-28
120
1
2018-03-28
514
1
2018-03-30
426
2
2018-02-11
125
2
2018-03-01
547
3
2018-02-10
588
3
2018-04-03
111
4
2018-02-10
697
5
2018-04-02
403
5
2018-04-05
321
6
2018-04-09
909
11
2018-10-25
8401
You need a few building blocks for this. Here is the data model I used:
<edit>
I see user_id in the different tables are not the same, in that case you can omit the relationship between the tables and the two relationships from the Calendar table will both be active - with no need to change the relationship semantics in the count_of_customer measure. </edit>
The calendar table is important because we can't rely on one single date column to aggregate data from different tables, so we create a common calendar table with this sample DAX code:
Calendar =
ADDCOLUMNS (
CALENDARAUTO () ,
"Year" , YEAR ( [Date] ) ,
"Month" , FORMAT ( [Date] , "MMM" ) ,
"Month-Year" , FORMAT ( [Date] , "MMM")&"-"&YEAR ( [Date] ) ,
"YearMonthNo" , YEAR ( [Date] ) * 12 + MONTH ( [Date] ) - 1
)
Make sure to sort the Month-Year column by the YearMonthNo column so your tables look nice:
Set your relationships as shown with the active relationship from Calendar to user - if not the measures will not work unless you alter the relationships accordingly in the code! In my data model the inactive relationship is between Calendar and customer order.
Next up are the measures we will use for this. First off we count the users, a simple row count:
count_of_users = COUNTROWS ( user )
Then we count distinct user ids in the order table to count customers, here we need to use the inactive relationship between Calendar and customer order and to do this we have to invoke CALCULATE:
count_of_customers =
CALCULATE (
DISTINCTCOUNT ( 'customer order'[user_id] ) ,
USERELATIONSHIP (
'Calendar'[Date] ,
'customer order'[order_date]
)
)
We can use this measure to count users cumulatively:
cumulative_users =
VAR _maxVisibleDate = MAX ( 'Calendar'[Date] )
RETURN
CALCULATE (
[count_of_users] ,
ALL ( 'Calendar' ) ,
'Calendar'[Date] <= _maxVisibleDate
)
And this measure to count cumulative customers per month:
cumulative_customers =
VAR _maxVisibleDate = MAX ( 'Calendar'[Date] )
RETURN
CALCULATE (
SUMX (
VALUES ( 'Calendar'[YearMonthNo] ) ,
[count_of_customers]
),
ALL ( 'Calendar' ) ,
'Calendar'[Date] <= _maxVisibleDate
)
Lastly we want the ratio of these last cumulative measures:
cumulative_customers/users =
DIVIDE (
[cumulative_customers] ,
[cumulative_users]
)
And here is your result:

DATEDIFF between 2 rows aggregating by 2 columns DAX

I have a big data set with the structure as shown below.
Operation
User
Timestamp
Elapsed time
12
1
2018-01-03
11:19:02 AM
12
1
2018-01-03
12:34:02 PM
12
1
2018-01-04
8:34:02 AM
12
2
2018-02-03
9:34:02 AM
12
2
2018-02-03
11:12:42 AM
12
3
2018-02-03
12:12:00 PM
15
1
2018-01-02
9:22:32 AM
15
1
2018-01-02
9:25:32 AM
15
2
2018-01-02
9:25:32 AM
The goal is to form the column "Elapsed Time" using DAX and PowerBI. The column shows the difference/duration between the current timestamp and previous timestamp for the same user and the same operation.
I've tried something along the lines of:
Elapsed time =
DATEDIFF (
CALCULATE (
MAX ( data[Timestamp] ),
ALLEXCEPT ( data, data[Operation], data[User] ),
data[Timestamp] < EARLIER ( data[Timestamp] )
),
data[Timestamp],
MINUTE
)
`
But it complains about a single value for column 'Timestamp' in table 'data' cannot be determined. this can happen when a measure formula refers to a column that contains many values without specifying an aggregator such as min, max, count, or sum to get a single result.
I'm very new to DAX, so I'd appreciate any help.
Since the 'Table'[Operation] and 'Table'[User] of the current row are to be used as filter, a very simple approach might just use CALCULATE to trigger the context transition, transforming the current row context to the corresponding filter context, and then to replace the filer over 'Table'[Timestamp] to be less than the current Timestamp, previously saved to a variable. The context transition automatically sets the correct filters over 'Table'[Operation] and 'Table'[User]
Elapsed time =
VAR CurrentTimestamp = 'Table'[TimeStamp]
RETURN
DATEDIFF (
CALCULATE ( MAX ( 'Table'[Timestamp] ), 'Table'[Timestamp] < CurrentTimestamp ),
CurrentTimestamp,
MINUTE
)
Typing on the mobile, so apologies for possible errors. Assuming this is a calculated column:
Elapsed time =
DATEDIFF (
CALCULATE (
MAX ( Table[Timestamp] ),
FILTER (
Table,
Table[User] = EARLIER ( Table[User] )
&& Table[Operation] = EARLIER ( Table[Operation] )
&& Table[Timestamp] < EARLIER ( Table[Timestamp] )
)
),
Table[Timestamp],
MINUTE
)
Where Table is your table name.
There surely are now ways to do that, do apologies for non optimal approach.

Daily Table out of Start and End Date

I'm trying to create a calculated table with daily information of employees based on MIN and MAX dates. I'm on Power BI.
This won't be super-efficient if you have too many employees and dates, but you can take the cartesian product of the list of employees with the list of all possible days and filter that down:
CalculatedTable =
VAR CartesianProduct =
CROSSJOIN (
VALUES ( Main[employee_number] ),
CALENDAR ( MIN ( Main[start] ), MAX ( Main[end] ) )
)
RETURN
FILTER (
CartesianProduct,
[Date] >= LOOKUPVALUE ( Main[start], Main[employee_number], [employee_number] ) &&
[Date] <= LOOKUPVALUE ( Main[end], Main[employee_number], [employee_number] )
)
The CALENDAR function generates a table with column Date starting from the first argument and includes all days up to the second argument.
I'm not sure how to do this more efficiently in DAX, but I can think of a cleaner solution in M (query editor language).

Calculate price based on distinct count

I am having trouble working out a measure (Revenue) in power bi.
I have a measure which is basically counting distinct values in a table (table 1). From this column I want to multiply the distinct count to get the total price (prices are in another table).
See below for an example
Table 1
Product DistinctCount Revenue (Measure I am trying to Calculate)
A 15 45.00
B 30 60.00
Prices Table
Product Price
A 3.00
B 2.00
At the moment the Revenue is calculating based on COUNT and not DISTINCTCOUNT.
Any help would be much appreciated.
thanks!
Measures, Calculated Columns, Google
I am assuming you have a relationship set up between these two tables on [Product]. If this is the case you can do something like this to create a calculated column:
Revenue =
CALCULATE (
SUMX ( 'Table 1', 'Table 1'[DistinctCount] * RELATED ( 'Prices Table'[Price] ) )
)
If you are trying to create a table visual try the DAX below, where ID is just a transaction ID for each product in your 'Table 1':
Revenue =
VAR DistinctCountOfProductTransactions =
CALCULATE ( DISTINCTCOUNT ( 'Table'[Id] ) )
VAR Result =
CALCULATE (
DistinctCountOfProductTransactions * SUM ( Prices[Price] ),
TREATAS ( VALUES ( 'Table'[Product] ), Prices[Product] )
)
RETURN
Result