Row number partition by to POWER BI DAX query - powerbi

Can someone help me to convert the sql string to Dax?
row_number() p over (partition by date, customer, type order by day)
The row number is my desired output.

Assuming that your data looks like this table:
Sample
+------------+----------+---------+--------+
| Date | Customer | Product | Gender |
+------------+----------+---------+--------+
| 01/01/2018 | 1234 | P2 | F |
| 01/01/2018 | 1234 | P2 | M |
| 03/01/2018 | 1235 | P1 | F |
| 03/01/2018 | 1235 | P2 | F |
+------------+----------+---------+--------+
I have created a calculated column called Rank, using the RANKX and FILTER function.
The first part of the calculation is to create variables outside the scope of the FILTER function. The second part uses RANKX that takes an expression value - in this case Gender - to order the values.
Rank =
VAR _currentdate = 'Sample'[Date]
VAR _customer = 'Sample'[Customer]
var _product = 'Sample'[Product]
return
RANKX(FILTER('Sample',
[Date]=_currentdate &&
[Customer] = _customer &&
[Product] = _product),[Gender],,ASC)
The output is
I contrasted the output to the SQL equivalent.
select
*,
row_number() over(partition by Date,Customer,Product order by Gender)
from (
select '2018-01-01' as Date,1234 as CUSTOMER,'P2' AS PRODUCT, 'M' Gender union
select '2018-01-01' as Date,1234,'P2','F' UNION
select '2018-01-03' as Date,1235,'P1','F' UNION
select '2018-01-03' as Date,1235,'P2','F'
)t1

Related

Usage of TSQL string_split in DAX

I have 2 tables in SSAS / Power BI:
Table1:
| ValueName| ValueKey |
|:---- |:------: |
| abc | 1,2,3 |
Table2:
| ID | ValueKey | Value |
|:---- |:------: |:------: |
| ID1 | 1 | 87,8 |
| ID2 | 85 | 14 |
| ID3 | 90 | 95,8 |
| ID4 | 3 | 13,4 |
I need to retrieve (in temp table, later make calculations over this temp table) ID, Value and only those rows, which have ValueKey 1 or 2 or 3.
I need to do it with DAX. In SQL we have for such situation STING_SPLIT function. Is there some way how can I achive this with DAX? My ValueKey column (table1) is comma separated text and ValueKey (table2) column is INT.
Thanks in advance
Like #Jeroen Mostert suggests, you can do this by abusing the PATHCONTAINS function like this:
FilteredTable2 =
VAR CurrKey = SELECTEDVALUE ( Table1[ValueKey] )
VAR PathFromKey = SUBSTITUTE ( CurrKey, ",", "|" ) /* Paths use | as separator. */
RETURN
FILTER ( Table2, PATHCONTAINS ( PathFromKey, Table2[ValueKey] ) )
However, this is not best practice for relating tables. In general, you don't want multiple keys in a single fields.

Get latest value for each ID in Power BI / DAX measure

In Power BI I would like to create a DAX measure that will retrieve the latest string value for specific IDs. Example source table:
Name_ID | Name | DateTime | Value
----------------------------------------------------------
1 | Child_1 | 18.8.2021 12:33:24 | F
32 | Parent_32 | 18.8.2021 11:41:09 | F
13 | Child_1 | 18.8.2021 11:30:58 | E
48 | Parent_48 | 18.8.2021 09:13:11 | F
2 | Child_2 | 17.8.2021 00:09:42 | S
1 | Child_1 | 17.8.2021 23:03:34 | F
48 | Parent_48 | 17.8.2021 21:46:27 | S
6 | Parent_6 | 16.8.2021 17:31:26 | S
.
.
.
specific parents IDs for example here are 6, 32 and 48, so the result should be something like this:
Name_ID | Name | DateTime (of last execution) | Value
------------------------------------------------------------------------------
32 | Parent_32 | 18.8.2021 11:41:09 | F
48 | Parent_48 | 18.8.2021 09:13:11 | F
6 | Parent_6 | 16.8.2021 17:31:26 | S
The result table I'm trying to get is only parents latest appearance and retrieving the whole row or just Value from last column.
This seems so easy in theory and on paper but I just can't seem to get it in DAX I have tried with various calculate formulas but without any result worth mentioning .
I'm beginner in Power Bi and any help would be very appreciated!
You can use a measure like this one, where we check Max Date per Name:
Flag =
var MaxDatePerName = CALCULATE(max(Sheet3[DateTime]), FILTER(ALL(Sheet3), SELECTEDVALUE(Sheet3[Name]) = Sheet3[Name]))
return
if( MaxDatePerName = SELECTEDVALUE(Sheet3[DateTime]) && LEFT(SELECTEDVALUE(Sheet3[Name]),6) = "Parent", 1, BLANK())
With RANKX
Measure2 =
VAR _0 =
MAX ( 'Table 1'[DateTime] )
VAR _00 =
MAX ( 'Table 1'[Name] )
VAR _1 =
CALCULATE (
RANKX (
FILTER ( ALL ( 'Table 1' ), 'Table 1'[Name] = _00 ),
CALCULATE ( MAX ( 'Table 1'[DateTime] ) ),
,
DESC
)
)
VAR _2 =
IF ( _1 = 1 && CONTAINSSTRING ( _00, "Parent" ) = TRUE (), _0, BLANK () )
RETURN
_2

How to generate rank in Power BI on the basis of two column

I am new to Power BI and need some help regarding the Power BI RANKX function
So the scenario is I have Emp name and emp_id fields in my employee table and I have the office_distance and emp id column from the office table.
I want to create a column in my visual which contains ranking on the distance and name basis.
Example:
| EmpName | off_dist | Rank |
|-------- |----------|------|
| A | 10 | 1 |
| A | 20 | 2 |
| A | 30 | 3 |
| B | 20 | 3 |
| B | 10 | 1 |
| B | 15 | 2 |
Please let me know how can I achieve this
Please refer to below DAX formulas for calculated columns. And if this post helps, then please consider Accept it as the solution to help the other members find it more quickly.
Create a column to rank by the Employee Name
Rank EName = RANKX(ALL(Table), U381[Table], ,ASC, Dense)
Create another column to rank by Employee Name and by the Office Distance.
Ranking on EName and Distance =
VAR X = MAX('Table'[Rank E_Name])
var result =
RANKX(
ALL(Table),
Table[O_Distance] * X + Table[Rank E_Name], ,
ASC
)
RETURN
result

Daily Rank Power BI

I have a table with the following headers:
Dates | Category | Value
1/1/00 | A | 100
1/1/00 | B | 200
1/2/00 | A | 300
1/2/00 | B | 100
What I would like to do is to be able to add a custom column with the daily rank as such:
Dates | Category | Value | Rank
1/1/00 | A | 100 | 1
1/1/00 | B | 200 | 2
1/2/00 | A | 300 | 2
1/2/00 | B | 100 | 1
My goal is to run calcs over the top for average rank, etc. How would I write the DAX code for this column?
Cheers
Try this as a calculated column:
Column =
VAR rankValue = 'table'[Value]
RETURN
CALCULATE (
RANK.EQ ( rankValue, 'table'[Value], ASC ),
ALLEXCEPT ( 'table', 'table'[Dates] )
)

How to calculate inventory per day from movement table with Power BI DAX?

I have a table with inventory movements. Each inventory item has a unique ID and they change status overtime (let's say status A, B, C and D, but not always in this order). Each status change of an ID is a new record in the table with the timestamp of the status change. My goal is to calculate with Power BI DAX the number of inventory at a certain day in status 'B'. The logic is to count the number of distinct IDs, which breached status 'B' before the certain day but doesn't have any newer status before that day.
Example of the source table:
ID | TimeStamp | Status
1 | 8/20/2018 | A
1 | 8/21/2018 | B
1 | 8/24/2018 | C
2 | 8/19/2018 | A
2 | 8/20/2018 | B
2 | 8/22/2018 | C
2 | 8/24/2018 | D
3 | 8/18/2018 | A
3 | 8/21/2018 | B
4 | 8/15/2018 | A
4 | 8/17/2018 | B
4 | 8/24/2018 | D
Example of the output table:
Date | Count of Items in Status B on this Day
8/17/2018 | 3
8/18/2018 | 2
8/19/2018 | 0
8/20/2018 | 8
8/21/2018 | 10
8/22/2018 | 5
8/23/2018 | 3
I was thinking of creating a table for the latest timestamp with status 'B' for each ID and then look for the next timestamp, after the timestamp of status 'B', if applicable:
ID (primary key) | TimeStamp of 'B' breached | TimeStamp of next status breach
1 | 8/20/2018 | 8/21/2018
2 | 8/18/2018 | 8/22/2018
3 | 8/21/2018 |
4 | 8/15/2018 | 8/20/2018
Then I would plug the above data into the Date context and count the number of IDs from the above table, where the "TimeStamp of 'B' breached" value is smaller AND the "TimeStamp of next status breach" value is greater than the certain date.
Unfortunately I am not sure how to plug this logic into DAX syntax, hence any recommendations would be appreciated.
Thanks a lot!
Gergő
This is a bit tricky, but we can do it with the use of a temporary calculated summary table within a measure:
CountStatusB =
SUMX(
ADDCOLUMNS(
SUMMARIZE(
FILTER(
ALL(Inventory),
Inventory[TimeStamp] <= MAX(Inventory[TimeStamp])
),
Inventory[ID],
"LastTimeStamp",
MAX(Inventory[TimeStamp])
),
"Status",
LOOKUPVALUE(Inventory[Status],
Inventory[ID], Inventory[ID],
Inventory[TimeStamp], [LastTimeStamp])
),
IF([Status] = "B",
1,
0
)
)
First, we create a summary table which calculates the last TimeStamp for each ID value. To do this, we use the SUMMARIZE function on a filtered table where we only consider dates from the current day or earlier, group by ID, and calculated the max TimeStamp.
Once we have the maximum TimeStamp per ID for the current day, we can look up what the Status is on that day and add that as a column to the summary table.
Once we know the most recent Status for each ID for the current day, we just need to sum up the ones where that Status is "B" and ignore the other ones.
It may be easier to read the measure if we break it up into steps. Here's the same logic as before, but using variables for more clarity.
CountB =
VAR CurrDay = MAX(Inventory[TimeStamp])
VAR Summary = SUMMARIZE(
FILTER(
ALL(Inventory),
Inventory[TimeStamp] <= CurrDay
),
Inventory[ID],
"LastTimeStamp",
MAX(Inventory[TimeStamp])
)
VAR LookupStatus = ADDCOLUMNS(
Summary,
"Status",
LOOKUPVALUE(Inventory[Status],
Inventory[ID], Inventory[ID],
Inventory[TimeStamp], [LastTimeStamp]
)
)
RETURN SUMX(LookupStatus, IF([Status] = "B", 1, 0))