Forum Discussion
Product table and subscription table
expected result
Hello,
I have a product table that looks like that:
| Product Id | Product Name |
| 1 | Product Y |
| 2 | Product X |
| 3 | Product Z |
And I have a Subscription Product Status table that a product can be in Status "Active" or "Not Active".
| Table Id (Unique) | Product Id | Status | Status Date |
| 1 | 1 | Active | 20/01/2018 |
| 2 | 1 | Not Active | 23/01/2018 |
| 3 | 2 | Active | 28/01/2018 |
| 4 | 3 | Active | 14/05/2018 |
| 5 | 1 | Active | 06/03/2019 |
| 6 | 1 | Not Active | 12/08/2019 |
| 7 | 3 | Not Active | 24/02/2020 |
| 8 | 1 | Active | 06/06/2020 |
| 9 | 2 | Not Active | 22/12/2021 |
| 10 | 3 | Active | 02/03/2022 |
As you can see this Subscription Status Table holds the historical status of every product, and every row represents a status change.
My goal is eventually to create a visual that shows Every month the number of Active products that I had.
I need a formula to create a measure to achieve this goal.
Thank you
I have updated the solution as requested to only check if the product was still active at the end of the month. (Originally you implied you wanted active anytime of the month)
Click here to download a solution
Now please click thumbs up and accept as solution.
It is not fair to keep changing to problem description.
If we the fix the problem then please accept the solution and raise a new ticket if you want to change the problem description.WasActive =// This measure returns a TRUE if the product was still active at the begining of the periodVAR mindate = MIN('Calendar'[Date])VAR maxdate = MAX('Calendar'[Date])VAR previousid =CALCULATE(MAX(Facts[Table Id]),ALL(Facts[Status Date]),Facts[Status Date] < mindate)VAR previousstatus =CALCULATE(SELECTEDVALUE(Facts[Status]),ALL(Facts),Facts[Table Id] = previousid)RETURNIF(previousstatus = "Active", TRUE())IsActive =// This measure returns// a TRUE if the product was set active at the end of the period// a FALSE if the product was set not active at the end of the period// the previous months valued if it was not set this monthVAR mindate = MIN('Calendar'[Date])VAR maxdate = MAX('Calendar'[Date])VAR lastid =CALCULATE(MAX(Facts[Table Id]),ALL(Facts[Status Date]),Facts[Status Date] >= mindate && Facts[Status Date] <= maxdate)VAR laststatus =CALCULATE(SELECTEDVALUE(Facts[Status]),ALL(Facts),Facts[Table Id] = lastid)RETURNSWITCH(TRUE(),laststatus = "Active", TRUE(),laststatus = "Not Active", FALSE(),[WasActive])ActiveProducts =// This measure counts the number or products that were active
SUMX(VALUES(Products[Product Id]),INT([IsActive]))Hi xl0911
I don't understand what is the problem. Here is your sample file with the very same code
46 Replies
- speedramps
Super User
Sorry @tamerj1, I think there is a bug in your DAX
Only one product was active in Feb 2018 but your report shows two.
Thanks for trying to help xl0911
Please can you double check my solution (see above).
Two pairs of eyes are better than one.- tamerj1
Community Champion
yes you are right. I will fix once I reach home
- speedramps
Super User
@xl0911 I have accepted my solution because I proivided 2 solutions that worked but you keep changing the problem description.
In future when you raise a problem, please show your thanks to volunteers who help with a thumb click and accept the solution. One question per ticket please. If you need to extend your request then please raise a new ticket.
You will get a quicker response and each volunteer solver will get the kudos they deserve. Thank you !
- tamerj1
Community Champion
Hi xl0911
Here is the a sample file with the solution https://we.tl/t-RX6Wox2KRZ# Active Subscriptions = SUMX ( VALUES ( Products[Product Id] ), CALCULATE ( VAR CurrentDate = MAX ( 'Date'[Date] ) VAR PreviousTable = FILTER ( Subscription, Subscription[Status Date] <= CurrentDate ) VAR PreviousActiveTable = FILTER ( PreviousTable, Subscription[Status] = "Active" ) VAR LastActivation = MAXX ( PreviousActiveTable, Subscription[Status Date] ) VAR PreviousIactctiveTable = FILTER ( PreviousTable, Subscription[Status] <> "Active" && Subscription[Status Date] > LastActivation ) VAR LastInactivation = COALESCE ( MAXX ( PreviousIactctiveTable, Subscription[Status Date] ), DATE ( 3000, 1, 1 ) ) RETURN IF ( CurrentDate <= LastInactivation && CurrentDate >= LastActivation, 1 ) ) )- xl0911
Helper III
Thank you tamerj1,
Two things please:
1. In my original schema my date table already has relationship, so I guess I need to add USERELATIONSHIP function (but I dont know where to add it)
2. It seams that the result I'm getting is not in "running total", I'm sorry that i wasn't more clear.
- speedramps
Super User
Thank you xl0911 for a very clear explantion of your problem with example data as tables (not screen shots).
So I could import the data and build this solution. Wish all members gave such clear decsriptions!Click here to download the solution
Quote speedramps when you raise new problems if you can describe them all as nicely as this and I will receive an notification.
I created 3 measures
WasActive =// This measure returns a TRUE is the product was still active at the begining of the periodVAR mindate = MIN('Calendar'[Date])VAR maxdate = MAX('Calendar'[Date])VAR previousid =CALCULATE(MAX(Facts[Table Id]),ALL(Facts[Status Date]),Facts[Status Date] < mindate)VAR previousstatus =CALCULATE(SELECTEDVALUE(Facts[Status]),ALL(Facts),Facts[Table Id] = previousid)RETURNIF(previousstatus = "Active", TRUE())IsActive =// This measure returns a TRUE is the product was set to active at any time duting the periodVAR mindate = MIN('Calendar'[Date])VAR maxdate = MAX('Calendar'[Date])VAR activethisperiod =CALCULATE(SELECTEDVALUE(Facts[Status]),ALL(Facts[Status Date]),Facts[Status Date] >= mindate && Facts[Status Date] <= maxdate,Facts[Status] = "Active")RETURNIF(activethisperiod = "Active", TRUE())ActiveProducts =// This measure counts the number or products that were either active at the begining of the period or were set to active during the periodSUMX(VALUES(Products[Product Id]),INT( [IsActive] || [WasActive]))My report shows the active products per month in the top left.The top right visual is an audit trail to help with testing.The bottom righ is your source data.If you clcic a product in the audit report them the source data will filter accordingly to help with testing.- xl0911
Helper III
Thank you speedramps
I think your solution is not what I meant because Product Id 1 is not active in the end of the month so under product Id 1 in jan-2018 the count should be 0.
- speedramps
Super User
I have updated the solution as requested to only check if the product was still active at the end of the month. (Originally you implied you wanted active anytime of the month)
Click here to download a solution
Now please click thumbs up and accept as solution.
It is not fair to keep changing to problem description.
If we the fix the problem then please accept the solution and raise a new ticket if you want to change the problem description.WasActive =// This measure returns a TRUE if the product was still active at the begining of the periodVAR mindate = MIN('Calendar'[Date])VAR maxdate = MAX('Calendar'[Date])VAR previousid =CALCULATE(MAX(Facts[Table Id]),ALL(Facts[Status Date]),Facts[Status Date] < mindate)VAR previousstatus =CALCULATE(SELECTEDVALUE(Facts[Status]),ALL(Facts),Facts[Table Id] = previousid)RETURNIF(previousstatus = "Active", TRUE())IsActive =// This measure returns// a TRUE if the product was set active at the end of the period// a FALSE if the product was set not active at the end of the period// the previous months valued if it was not set this monthVAR mindate = MIN('Calendar'[Date])VAR maxdate = MAX('Calendar'[Date])VAR lastid =CALCULATE(MAX(Facts[Table Id]),ALL(Facts[Status Date]),Facts[Status Date] >= mindate && Facts[Status Date] <= maxdate)VAR laststatus =CALCULATE(SELECTEDVALUE(Facts[Status]),ALL(Facts),Facts[Table Id] = lastid)RETURNSWITCH(TRUE(),laststatus = "Active", TRUE(),laststatus = "Not Active", FALSE(),[WasActive])ActiveProducts =// This measure counts the number or products that were active
SUMX(VALUES(Products[Product Id]),INT([IsActive]))
- speedramps
Super User
Ha Ha I see that tamerj1 has also posted solution.
Execllent !
It will be interesting to compare the output from both methods and see if they produce the same results.
- tamerj1
Community Champion
Hi xl0911
Here is the updated solution with active relationship with the date table and fixed the bug noticed by speedramps# Active Subscriptions = SUMX ( VALUES ( Products[Product Id] ), CALCULATE ( VAR PeriodStartDate = MIN ( 'Date'[Date] ) VAR PeriodEnadDate = MAX ( 'Date'[Date] ) VAR TableBeforePeriodEnd = FILTER ( Subscription, Subscription[Status Date] <= PeriodEnadDate ) VAR PreviousActiveTable = FILTER ( TableBeforePeriodEnd, Subscription[Status] = "Active" ) VAR LastActivation = COALESCE ( MAXX ( PreviousActiveTable, Subscription[Status Date] ), DATE ( 3000, 1, 1 ) ) VAR TableBeforePeriodStart = FILTER ( Subscription, Subscription[Status Date] < PeriodStartDate ) VAR PreviousIactctiveTable = FILTER ( TableBeforePeriodStart, Subscription[Status] <> "Active" ) VAR LastInactivation = COALESCE ( MAXX ( PreviousIactctiveTable, Subscription[Status Date] ), DATE ( 3000, 1, 1 ) ) VAR Result = IF ( PeriodEnadDate >= LastActivation && PeriodStartDate <= LastInactivation, 1 ) RETURN Result, CROSSFILTER ( 'Date'[Date], Subscription[Status Date], None ) ) )I wanted to upload more screenshots but seems I reached my maximum allowable limit of uploaded images!
- xl0911
Helper III
Thank you.
I'm getting this error "The expression refers to multiple columns. Multiple columns cannot be converted to a scalar value."
I guess that maybe the formula can't handle a scenario that maybe a product has 2 rows of status in the same date... ?
- Ashish_Mathur
Super User
- xl0911
Helper III
I think your solution is not what I meant because Product Id 1 is not active in the end of the month so under product Id 1 in jan-2018 the count should be 0.
- tamerj1
Community Champion
Hi xl0911
This version is working perfectly in the sample file. Please download the sample file and compare with yours. https://we.tl/t-c14Wj8tpax# Active Subscriptions = SUMX ( VALUES ( Products[Product Id] ), CALCULATE ( VAR PeriodEnadDate = MAX ( 'Date'[Date] ) VAR TableBeforePeriodEnd = FILTER ( Subscription, Subscription[Status Date] <= PeriodEnadDate ) VAR PreviousActiveTable = FILTER ( TableBeforePeriodEnd, Subscription[Status] = "Active" ) VAR LastActivation = COALESCE ( MAXX ( PreviousActiveTable, Subscription[Status Date] ), DATE ( 3000, 1, 1 ) ) VAR PreviousIactctiveTable = FILTER ( TableBeforePeriodEnd, Subscription[Status] <> "Active" && Subscription[Status Date] > LastActivation ) VAR LastInactivation = COALESCE ( MAXX ( PreviousIactctiveTable, Subscription[Status Date] ), DATE ( 3000, 1, 1 ) ) VAR Result = IF ( PeriodEnadDate >= LastActivation && PeriodEnadDate <= LastInactivation, 1 ) RETURN COALESCE ( Result, 0 ), CROSSFILTER ( 'Date'[Date], Subscription[Status Date], None ) ) )