Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Register now to learn Fabric in free live sessions led by the best Microsoft experts. From Apr 16 to May 9, in English and Spanish.

Reply
NikiTiki
Regular Visitor

Count the number of products that have moved from one status to another

Dear forum users

Has anyone encountered tracking product status changes from period to period?
I have the following table:


iddatestatus
12021-01A
12021-02A
12021-05B
12021-06C
12021-07A
22021-01C
22021-05C
22021-06A
22021-07A
22021-08B
32021-01C
32021-03A
32021-05A
32021-06B
32021-08C


Also I have two filters that work as data at the beginning of the period and data at the end of the period (not between)
For example : start_date filter - 2021-01 and end_date 2021-05

I see that like:
Product with id = 1 on 2021-01 has status A and on 2021-05 has status B and so on.

Start_dateEnd_dateIdStartEnd
2021-012021-051AB
2021-012021-052CC
2021-012021-053CA



And as result, i wish have a table like:

start_statusend_statusCount
AA0
AB1
AC0
AD0
BA0
BB0
BC0
BD0
CA1
CB0
CC1
CD0
DA0
DB0
DC0
DD0


And for example for date 2021-02 and 2021-07

Start_dateEnd_dateIdStartEnd
2021-022021-071AA
2021-022021-072DA
2021-022021-073DD


And result table

start_statusend_statusCount
AA1
AB0
AC0
AD0
BA0
BB0
BC0
BD0
CA0
CB0
CC0
CD0
DA1
DB0
DC0
DD1


Maybe someone has already tracked this? I will be grateful for help!



1 ACCEPTED SOLUTION

Ok, I get it now.

 

I changed the cross join status table script to this to add the D status

StatusFromTo = 

VAR Statuses = CALCULATETABLE(values('status'[status]))
VAR Statuses2 = UNION(SELECTCOLUMNS(Statuses,"statusFrom",'status'[status]),ROW("status","D"))
VAR Statuses3 = UNION(SELECTCOLUMNS(Statuses,"statusTo",'status'[status]),ROW("status","D"))
VAR Statuses4 = CROSSJOIN(Statuses2,Statuses3) 
RETURN Statuses4

 

And the measure to this

statusCount = 
VAR vPeriodFrom = CALCULATE( MIN(PeriodFromTo[PeriodFrom]), ALLSELECTED(PeriodFromTo[PeriodFrom]) )
VAR vPeriodTo = CALCULATE( max(PeriodFromTo[PeriodTo]), ALLSELECTED(PeriodFromTo[PeriodFrom]) )

VAR vStatusFrom = values(statusFromTo[statusFrom])
VAR vStatusTo = values(statusFromTo[statusTo])

VAR statuses = FILTER('status','status'[date]=vPeriodFrom)
VAR statuses2 = FILTER('status','status'[date]=vPeriodTo)

VAR statuses3 = VALUES('status'[id])

VAR statuses4 = NATURALINNERJOIN(NATURALLEFTOUTERJOIN(SELECTCOLUMNS(DISTINCT('status'[id]),"id",'status'[id]),SELECTCOLUMNS(statuses,"id",'status'[id],"status1",'status'[status])), SELECTCOLUMNS(statuses2,"id",'status'[id],"status2",'status'[status]))

RETURN COUNTROWS(FILTER(statuses4,COALESCE([status1],"D") in vStatusFrom && COALESCE([status2],"D") in vStatusTo))+0

 

I have updated the attached pbix file.

 

Please let me know if that works for you.

View solution in original post

6 REPLIES 6
daniel79
Resolver II
Resolver II

Here's my take on this.

 

First I created a table to be able to select period from and to

 

PeriodFromTo = 
VAR YearStart = int(left(min('status'[date]),4))
VAR YearFinish = int(left(max('status'[date]),4))
VAR Periods = SELECTCOLUMNS(GENERATESERIES(1,12),"Period",[Value])
VAR Years = SELECTCOLUMNS(GENERATESERIES(YearStart, YearFinish),"Year",[Value])

VAR Periods2 = CROSSJOIN(Years, Periods)
VAR Periods3 = SELECTCOLUMNS(Periods2,"PeriodFrom", [Year] & "-" & right("0" & [Period],2))
VAR Periods4 = SELECTCOLUMNS(Periods2,"PeriodTo", [Year] & "-" & right("0" & [Period],2))
VAR Periods5 = FILTER(CROSSJOIN(Periods3, Periods4), [PeriodFrom]<=[PeriodTo])
RETURN Periods5

 

 

Then I created a table to cross join possible status

 

StatusFromTo = 

VAR Statuses = CALCULATETABLE(values('status'[status]))
VAR Statuses2 = SELECTCOLUMNS(Statuses,"statusFrom",'status'[status])
VAR Statuses3 = SELECTCOLUMNS(Statuses,"statusTo",'status'[status])
VAR Statuses4 = CROSSJOIN(Statuses2,Statuses3) 
RETURN Statuses4

 

 

And finally created a meassure to calculate the products that switched from a one status to the other one

 

statusCount = 
VAR vPeriodFrom = CALCULATE( MIN(PeriodFromTo[PeriodFrom]), ALLSELECTED(PeriodFromTo[PeriodFrom]) )
VAR vPeriodTo = CALCULATE( max(PeriodFromTo[PeriodTo]), ALLSELECTED(PeriodFromTo[PeriodFrom]) )

VAR vStatusFrom = values(statusFromTo[statusFrom])
VAR vStatusTo = values(statusFromTo[statusTo])

VAR statuses = SUMMARIZE(FILTER('status','status'[date]<=vPeriodFrom),'status'[id],"date2",max('status'[date]))
VAR statuses2 = ADDCOLUMNS(FILTER(NATURALINNERJOIN('status',statuses),[date2]='status'[date]),"MINDATE",vPeriodFrom)

VAR statuses3 = SUMMARIZE(FILTER('status','status'[date]<=vPeriodTo),'status'[id],"date2",max('status'[date]))
VAR statuses4 = ADDCOLUMNS(FILTER(NATURALINNERJOIN('status',statuses3),[date2]='status'[date]),"MAXDATE",vPeriodTo)

VAR statuses5 = NATURALINNERJOIN(SELECTCOLUMNS(statuses2,"id",'status'[id],"status1",'status'[status]), SELECTCOLUMNS(statuses4,"id",'status'[id],"status2",'status'[status]))
RETURN COUNTROWS(FILTER(statuses5,[status1] in vStatusFrom && [status2] in vStatusTo))+0

 

 

pbix and data file in the following link.

Hello, Daniel!

Thank you very much for such great help!

I tried to understand your solution, and I will continue...but so far without success

But is it possible to change the measure for missed dates, consider that the product is in the "D" status, that is, from 2021-02 to 2021-08

statusFromstatusTostatusCount
AA0
AB0
AC0
AD1
BA0
BB0
BC0
BD0
CA0
CB0
CC0
CD0
DA0
DB1
DC1
DD0

Thank you for your help!!!

Hi, it is considering missed dates.

 

There was no "D" status in the sample data, can you please update your sample dataset and the expected result?

status D is not in the transactional table, this status means "missing"

result table, if select periodfrom 2021-02 and periodto 2021-08

 

statusFromstatusTostatusCount
AA0
AB0
AC0
AD1
BA0
BB0
BC0
BD0
CA0
CB0
CC0
CD0
DA0
DB1
DC1
DD0

 

Thank you again!

Ok, I get it now.

 

I changed the cross join status table script to this to add the D status

StatusFromTo = 

VAR Statuses = CALCULATETABLE(values('status'[status]))
VAR Statuses2 = UNION(SELECTCOLUMNS(Statuses,"statusFrom",'status'[status]),ROW("status","D"))
VAR Statuses3 = UNION(SELECTCOLUMNS(Statuses,"statusTo",'status'[status]),ROW("status","D"))
VAR Statuses4 = CROSSJOIN(Statuses2,Statuses3) 
RETURN Statuses4

 

And the measure to this

statusCount = 
VAR vPeriodFrom = CALCULATE( MIN(PeriodFromTo[PeriodFrom]), ALLSELECTED(PeriodFromTo[PeriodFrom]) )
VAR vPeriodTo = CALCULATE( max(PeriodFromTo[PeriodTo]), ALLSELECTED(PeriodFromTo[PeriodFrom]) )

VAR vStatusFrom = values(statusFromTo[statusFrom])
VAR vStatusTo = values(statusFromTo[statusTo])

VAR statuses = FILTER('status','status'[date]=vPeriodFrom)
VAR statuses2 = FILTER('status','status'[date]=vPeriodTo)

VAR statuses3 = VALUES('status'[id])

VAR statuses4 = NATURALINNERJOIN(NATURALLEFTOUTERJOIN(SELECTCOLUMNS(DISTINCT('status'[id]),"id",'status'[id]),SELECTCOLUMNS(statuses,"id",'status'[id],"status1",'status'[status])), SELECTCOLUMNS(statuses2,"id",'status'[id],"status2",'status'[status]))

RETURN COUNTROWS(FILTER(statuses4,COALESCE([status1],"D") in vStatusFrom && COALESCE([status2],"D") in vStatusTo))+0

 

I have updated the attached pbix file.

 

Please let me know if that works for you.

You did an incredible job, I hope one day to reach your level!!!

Thank you!

Helpful resources

Announcements
Microsoft Fabric Learn Together

Microsoft Fabric Learn Together

Covering the world! 9:00-10:30 AM Sydney, 4:00-5:30 PM CET (Paris/Berlin), 7:00-8:30 PM Mexico City

PBI_APRIL_CAROUSEL1

Power BI Monthly Update - April 2024

Check out the April 2024 Power BI update to learn about new features.

April Fabric Community Update

Fabric Community Update - April 2024

Find out what's new and trending in the Fabric Community.