PowerBI: same IDs for consecutive data - datatable

I have a question about generating IDs in power BI.
Question: I have the table like following:
I'd like to generate same IDs for consecutive data (it means that end date of previous row equals to start date of current row), that has equal values in column 'Type', but IDs have to be different, if data is not consecutive. The example of correct IDs are below.
(Note that 'Bike' has different Ids because these rows are NOT consecutive)
Can you help me please with writing DAX command or Query? Every advice would be very helpful.

I created 3 separate calculated columns in order to accomplish this , with the final IDs column being the result you're looking for. I've included the DAX below, just replace the "Table1" references with your table's name. Skip down to the bottom to see an image of how the final table looks (Results Table).
First Calculated Column
Create a unique string ID for each row in the table. Specify "Same" for rows that will inherit the previous unique ID. This makes use of the EARLIER function and a solution similar to Get Value from Previous Row post on the Community page in order to evaluate the previous row in a calculation.
First Iteration IDs =
VAR previousRow =
TOPN(
1,
FILTER(
Table1,
Table1[Start Date] < EARLIER(Table1[Start Date])
&& Table1[Type] = EARLIER(Table1[Type])
),
[Start Date],
DESC
)
VAR previousEndDate = MINX(previousRow, [End Date])
VAR previousType = MINX(previousRow, [Type])
RETURN
IF(
Table1[Start Date] = previousEndDate && Table1[Type] = previousType,
"Same",
CONCATENATE(FORMAT(Table1[Start Date], "dd/mm/yyyy"), CONCATENATE(" ", Table1[Type]))
)
Second Calculated Column
Convert all of the "Same" IDs from the previous column to their respective IDs in that column.
Second Iteration IDs =
VAR previousRow =
TOPN(
1,
FILTER(
Table1,
Table1[Start Date] < EARLIER(Table1[Start Date])
&& Table1[Type] = EARLIER(Table1[Type])
&& NOT(Table1[First Iteration IDs] = "Same")
),
[First Iteration IDs],
DESC
)
VAR previousID = MINX(previousRow, [First Iteration IDs])
RETURN
IF(
Table1[First Iteration IDs] = "Same",
previousID,
Table1[First Iteration IDs]
)
Third Calculated Column
Use the RANKX function to create more user-friendly number IDs from the string IDs in the previous column. This is the original column that you had asked for.
IDs = RANKX(Table1, Table1[Second Iteration IDs], , 1, Dense) - 1
I've included a results table below based on the sample table that you provided. You may need to play around with the unique string ID format or the RANKX function depending on how your actual data looks.

Related

Calculate the difference between the current and the previous row in DAX

In Analysis Services I have a table for Covid Cases, as shown below:
It shows the cumulative cases on a daily basis for 193 different countries. I would like to add a calculated column to calculate the difference between the current row and the previous row, so I can see the daily new cases. Also, as column Country/Region contains 193 different countries, this calculation needs to be somehow grouped for each country. The Date column should also be in the right order.
How should I sort the table and what DAX function should I use to make this work?
Try this
Column =
VAR current =
CALCULATE ( MAX ( tbl[Value] ) )
VAR prev =
MAXX (
FILTER (
tbl,
tbl[Country] = EARLIER ( tbl[Country] )
&& tbl[Date] < EARLIER ( tbl[Date] )
),
tbl[Value]
)
RETURN
current - prev

Tag accounts with highest rank in DAX

I have the following table in PowerPivot. I'd like to create a column ("Show") that will have the name of the quarter corresponding to the highest rank for all rows with the same ID. The table below shows the desired end state where "Show" is the calculated column I'm after:
Assuming your table is called 'DimShow', the following DAX should do the trick:
LOOKUPVALUE(
'DimShow'[Quarter],
'DimShow'[ID], 'DimShow'[ID],
'DimShow'[Rank],
CALCULATE(
MIN('DimShow'[Rank]),
ALLEXCEPT('DimShow', 'DimShow'[ID])
)
)
Explanation:
We want to lookup a value from the [Quarter] column that has the same [ID] as the current row. At the same time, the [Rank] value should be the minimum value for all rows that has the same [ID] as the current row.
Note that this will produce an error, if there are more than one distinct value of [Quarter] for the same (lowest) rank, within a specific [ID].
I usually use a variable to do this:
Show =
VAR TopRank = CALCULATE(MIN(Table1[Rank]), ALLEXCEPT(Table1, Table1[ID]))
RETURN CALCULATE(
MAX(Table1[Quarter]),
ALLEXCEPT(Table1, Table1[ID]),
Table1[Rank] = TopRank)
The TopRank variable calculates what the highest rank is for that ID. The second line essentially looks up what the Quarter value is for that rank and that ID.

Dax - Filter by value then count occurence in table

I am working with an employee table and was wondering if I could get some help.
My data table has rows with start and end date values. I filter these rows down using Filter(data table, [start date]<=[Measure.MaxMonth]&&[end date]>=[Measure.MaxMonth]. [Measure.MaxMonth] is a measure that sits on a disconnected date table and functions like a parameter.
Here is a formula that I have been testing but have not been getting the desired results:
Measure.DirectReports = CALCULATE(COUNTROWS(Data Table),filter(Data Table,Data Table[Mgr ID]=Data Table[Emp ID]&&Data Table[Start Date]<=[Meas.LastMonth]&&Data Table[End Date]>=[Meas.LastMonth]))
Measure.LastMonth = max(EOM[End of Month]) ->this value can equal any month end between July 2005 and July 2017. EOM is a date table with a row for each month end - 7/31/2005, 8/31/2005,....7/31/2017
This gives me a table structured liked this:
Emp ID,Emp Attr,Mgr ID,Start Date,End Date
1,B,4,10/1/2013,10/6/2013
1,B,4,10/7/2013,12/29/2013
1,B,4,12/30/2013,12/28/2014
1,B,8,12/29/2014,10/4/2015
1,B,8,10/5/2015,12/27/2015
1,B,12,12/28/2015,5/15/2016
1,B,12,5/16/2016,10/2/2016
1,B,12,10/3/2016,12/25/2016
2,B,4,12/1/2014,12/28/2014
2,B,4,12/29/2014,12/27/2015
2,B,4,12/28/2015,2/7/2016
2,B,4,2/8/2016,3/6/2016
2,B,8,3/7/2016,6/1/2016
3,B,6,7/1/2015,12/27/2015
3,B,8,12/28/2015,6/30/2016
3,B,6,7/1/2016,9/4/2016
3,B,6,9/5/2016,12/25/2016
3,B,6,12/26/2016,5/7/2017
3,B,4,5/8/2017,6/11/2017
3,B,4,6/12/2017,6/25/2017
3,B,4,6/26/2017,7/9/2017
3,B,19,7/10/2017,12/31/9999
4,A,,7/1/1996,4/2/2006
4,A,,4/3/2006,12/31/2007
4,A,,1/1/2008,5/22/2011
4,A,,5/23/2011,11/16/2014
4,A,,11/17/2014,6/11/2017
4,A,,6/12/2017,6/25/2017
4,A,,6/26/2017,12/31/9999
5,B,4,11/8/2010,1/2/2011
5,B,4,1/3/2011,5/22/2011
5,B,4,5/23/2011,1/1/2012
5,B,4,1/2/2012,5/31/2012
5,B,4,6/1/2012,7/1/2012
5,B,4,7/2/2012,9/7/2012
6,B,4,1/3/2011,5/22/2011
6,B,4,5/23/2011,9/5/2011
6,B,4,9/6/2011,1/1/2012
6,B,4,1/2/2012,12/30/2012
6,B,4,12/31/2012,12/29/2013
6,B,4,12/30/2013,5/18/2014
6,B,4,5/19/2014,11/16/2014
6,B,4,11/17/2014,12/28/2014
6,B,4,12/29/2014,3/22/2015
6,B,4,3/23/2015,12/27/2015
6,B,4,12/28/2015,3/6/2016
6,B,4,3/7/2016,8/21/2016
6,B,4,8/22/2016,10/30/2016
6,B,4,10/31/2016,12/25/2016
6,B,4,12/26/2016,1/8/2017
6,B,4,1/9/2017,5/7/2017
6,B,4,5/8/2017,6/11/2017
6,B,4,6/12/2017,6/25/2017
6,B,4,6/26/2017,12/31/9999
7,B,4,1/2/2012,12/30/2012
7,B,4,12/31/2012,12/29/2013
7,B,4,12/30/2013,5/18/2014
7,B,4,5/19/2014,11/16/2014
7,B,4,11/17/2014,12/28/2014
7,B,4,12/29/2014,3/8/2015
7,B,4,3/9/2015,1/18/2016
7,B,4,1/19/2016,2/19/2016
8,B,6,12/31/2012,11/3/2013
8,B,4,11/4/2013,12/29/2013
8,B,4,12/30/2013,1/26/2014
8,B,4,1/27/2014,5/18/2014
8,B,4,5/19/2014,11/16/2014
8,B,4,11/17/2014,12/28/2014
8,B,4,12/29/2014,3/22/2015
8,B,4,3/23/2015,12/27/2015
8,B,4,12/28/2015,7/1/2016
10,B,4,10/3/2011,12/18/2011
10,B,4,12/19/2011,12/30/2012
10,B,4,12/31/2012,2/23/2013
10,B,4,2/24/2013,11/20/2014
11,B,4,2/1/2011,2/27/2011
11,B,4,2/28/2011,5/1/2011
12,B,4,9/15/2012,12/31/2012
12,B,4,9/15/2012,12/31/2012
12,B,4,1/1/2013,12/31/2013
12,B,4,1/1/2013,4/30/2014
12,B,4,1/1/2014,4/30/2014
12,B,4,5/1/2014,11/16/2014
12,B,4,5/1/2014,12/28/2014
12,B,4,11/17/2014,11/30/2014
12,B,4,12/1/2014,12/28/2014
12,B,4,12/29/2014,12/27/2015
12,B,4,12/29/2014,12/30/2016
12,B,4,12/28/2015,12/30/2016
12,B,4,12/31/2016,12/31/2016
12,B,4,1/1/2017,6/11/2017
12,B,4,6/12/2017,6/25/2017
12,B,4,6/26/2017,7/9/2017
12,B,19,7/10/2017,12/31/9999
13,B,4,12/28/2015,9/4/2016
13,B,4,9/5/2016,12/25/2016
13,B,4,12/26/2016,6/11/2017
13,B,4,6/12/2017,6/25/2017
13,B,4,6/26/2017,12/31/9999
14,B,4,1/12/2015,12/27/2015
14,B,4,12/28/2015,12/25/2016
14,B,4,12/26/2016,6/11/2017
14,B,4,6/12/2017,6/25/2017
14,B,4,6/26/2017,12/31/9999
16,B,4,9/14/2015,10/19/2015
17,B,6,8/22/2016,12/25/2016
17,B,6,12/26/2016,5/7/2017
17,B,4,5/8/2017,6/11/2017
17,B,4,6/12/2017,6/25/2017
17,B,4,6/26/2017,7/9/2017
17,B,19,7/10/2017,12/31/9999
18,B,6,9/12/2016,12/25/2016
18,B,6,12/26/2016,5/7/2017
18,B,13,5/8/2017,6/11/2017
18,B,13,6/12/2017,6/25/2017
18,B,13,6/26/2017,7/9/2017
18,B,19,7/10/2017,12/31/9999
19,B,4,7/10/2017,12/31/9999
Empl ID is a unique employee number. Mgr ID references the Empl ID of the employee's manager at the desired point in time (Measure.LastMonth). Emp Attr is an attribute of the employee, such as level.
Does anyone have any ideas on how to create a measure that will count the occurrences of Empl ID in Mgr ID? Ideally, if I am creating a visual in Power BI and I filter based on Empl Attr ="A", can the resulting measure value give me the result = 3 -> the empl id "1" occurs 3 times in the mgr id column.
I need this to be a measure and not a calculated column so that I can trend the results over time (end of month on X axis in trend visual).
Thanks for the help and let me know if you have any questions!
Edit - Updating basically the entire answer due to new information about the problem.
I feel that your core problem is trying to create a relationship between two tables based on the evaluation of an expression (End of Month between Start Date and End Date). From my experience, the easiest way to workaround this is to CROSSJOIN the two tables and then filter it down based on whatever expression you would like. For this, I created a new table with this formula.
Results = DISTINCT(
SELECTCOLUMNS(
FILTER(
CROSSJOIN('Data Table', EOM),
'Data Table'[Start Date] <= EOM[End of Month] && 'Data Table'[End Date] >= EOM[End of Month]
),
"Emp ID", [Emp ID],
"End of Month", [End of Month]
)
)
One more piece before finally making the relationships, we need a list of unique employee IDs. That can easily be obtained by creating a new table with this formula.
Employees = DISTINCT(
SELECTCOLUMNS('Data Table',
"Emp ID", 'Data Table'[Emp ID]
)
)
From here, create relationships between all of the tables as shown in the image below.
I know you asked for a measure, but bear with me as I feel confident that this will get you what you want. Add a new column to the Results table with this formula.
DirectReports = CALCULATE(
COUNTROWS('Data Table'),
FILTER(ALL('Data Table'),
'Data Table'[Mgr ID] = EARLIER(Results[Emp ID]) &&
'Data Table'[Start Date] <= EARLIER(Results[End of Month]) &&
'Data Table'[End Date] >= EARLIER(Results[End of Month])
)
)
At this point, I would hide the Emp ID and End of Month from the results table and any other field(s) you desire. From there, make your visuals. For example, you said you wanted to show direct report count over time, so I made this simple line chart and card.

find rows with same value using LINQ

The issue with the image above is that
I want to apply a bonus share to the shareholders based on the TransLog_Date
Because the shareholder in row 1 has already transferred a portion of his shares to the holder in row 3, his new share value is what shows in row 2 column 5 as 100000
I want the bonus share to be calculated based on the value in row 2, column 5 but not on row 1, column 5.
I have tried several codes in LINQ but getting it wrong as the value is multiplied on all the 3 records which is totally wrong.
var transQuery = (from tq in db.TransactionsLogDbSet
where (tq.TransactionType == TransactionType.PurchaseOfShares)
|| (tq.TransactionType == TransactionType.TransferOfShares)
|| (tq.TransactionType == TransactionType.BonusSharesDeclared)
select tq);
var query = from row in db.TransactionsLogDbSet
group row by row.Transholder_ID into g
select new { Count = g.Count() };
OK, i think I finally got what you want.
Is that right?: Group all rows of some TransactionTypes by the Transholder_ID, then from each group select the row with the maximum Translog_Date, giving you the most recent row per Transholder_ID. Once you have the result of that, you can iterate over it to calculate whatever you need.
from t in db.TransactionLogDbSet
where where tq.TransactionType == TransactionType.PurchaseOfShares || tq.TransactionType == TransactionType.TransferOfShares || tq.TransactionType == TransactionType.BonusSharesDeclared
group t by t.Transholder_ID into g
select (from t1 in g orderby t1.Translog_Date descending select t1).First();
EDIT: I'll continue to edit the following part of my answer as long as we finally arrive at the correct query.
From you last comment so far it follows that you just want to select all rows with a TransLog_Date <= a given DateTime qualifiedDate.
from t in db.TransactionLogDbSet
where t.TransactionLog_Date <= qualifiedDate
select t
Is that it?

DAX - Lookup value to retrieve exchange rate

In table "Paypal", I have:
And in table "Câmbios":
And now, I'm adding a calculated column to "Paypal" table with the formula:
Câmbio = LOOKUPVALUE('Câmbios'[Câmbio];'Câmbios'[Mês];MONTH('Paypal'[Date]))
Which is returning the error:
A table of multiple values was supplied where a single value was expected.
This doesn't make sense to me.
Can anyone help?
Thanks
The problem is Câmbios table contains repeated values for at least one month and the LOOKUPVALUE function doesn't know which value use to retrieve the specified column.
You can use instead:
Cambio =
CALCULATE (
MAX ( Cambio[Cambio] ),
FILTER ( Cambio, [Mes] = MONTH ( EARLIER ( Paypal[Date] ) ) )
)
Or delete the repeated values from Cambios[Mes].

Resources