Forum Discussion

littlemojopuppy's avatar
littlemojopuppy
Community Champion
6 years ago

Customer Retention Calculation Over Successive Weeks

Hi!  Looking for a little advice.  Requirement is to calculate the number of customers who logged in on a given date, and then who logged in again in each of of the six one week time periods from that date.  Meaning for customers who logged in on May 31, how many of those customers logged in each of the periods June 1 - 7, June 8 - 14, June 15 - 21, etc.

I came up with a long formula that is correct.

Users Returning Within 42 Days:=VAR Weeks = 5
RETURN
    COUNTROWS (
        CALCULATETABLE (
            VALUES ( IdentityLog[IdentityId] ),
            -- Current Week
            CALCULATETABLE (
                VALUES ( IdentityLog[IdentityId] ),
                DATESINPERIOD (
                    'Calendar'[Date],
                    DATEADD (
                        LASTDATE ( 'Calendar'[Date] ),
                        ( Weeks * 7 ) + 1,
                        DAY
                    ),
                    7,
                    DAY
                )
            ),
            -- Previous Week
            CALCULATETABLE (
                VALUES ( IdentityLog[IdentityId] ),
                DATESINPERIOD (
                    'Calendar'[Date],
                    DATEADD (
                        LASTDATE ( 'Calendar'[Date] ),
                        ( ( Weeks - 1 ) * 7 ) + 1,
                        DAY
                    ),
                    7,
                    DAY
                )
            ),
            -- Two Weeks Ago
            CALCULATETABLE (
                VALUES ( IdentityLog[IdentityId] ),
                DATESINPERIOD (
                    'Calendar'[Date],
                    DATEADD (
                        LASTDATE ( 'Calendar'[Date] ),
                        ( ( Weeks - 2 ) * 7 ) + 1,
                        DAY
                    ),
                    7,
                    DAY
                )
            ),
            -- Three Weeks Ago
            CALCULATETABLE (
                VALUES ( IdentityLog[IdentityId] ),
                DATESINPERIOD (
                    'Calendar'[Date],
                    DATEADD (
                        LASTDATE ( 'Calendar'[Date] ),
                        ( ( Weeks - 3 ) * 7 ) + 1,
                        DAY
                    ),
                    7,
                    DAY
                )
            ),
            -- Four Weeks Ago
            CALCULATETABLE (
                VALUES ( IdentityLog[IdentityId] ),
                DATESINPERIOD (
                    'Calendar'[Date],
                    DATEADD (
                        LASTDATE ( 'Calendar'[Date] ),
                        ( ( Weeks - 4 ) * 7 ) + 1,
                        DAY
                    ),
                    7,
                    DAY
                )
            ),
            -- Five Weeks Ago
            CALCULATETABLE (
                VALUES ( IdentityLog[IdentityId] ),
                DATESINPERIOD (
                    'Calendar'[Date],
                    DATEADD (
                        LASTDATE ( 'Calendar'[Date] ),
                        ( ( Weeks - 5 ) * 7 ) + 1,
                        DAY
                    ),
                    7,
                    DAY
                )
            )
        )
    )

I was curious if anyone could suggest a more elegant solution.  I did see Greg_Deckler's blog post on For and While Loops in DAX.  But I couldn't get it to work properly because I need to pass groups of User IDs to compare and not a single value.

 

Any help would be appreciated!

6 Replies

  • v-lionel-msft's avatar
    v-lionel-msft
    Community Support

    Hi littlemojopuppy ,

     

    Maybe you can add an [Index] and simplify the code.

    Users Returning Within 42 Days = 
    VAR Weeks = 5
    RETURN
        COUNTROWS (
            CALCULATETABLE (
                VALUES ( IdentityLog[IdentityId] ),
                CALCULATETABLE (
                    VALUES ( IdentityLog[IdentityId] ),
                    DATESINPERIOD (
                        'Calendar'[Date],
                        DATEADD (
                            LASTDATE ( 'Calendar'[Date] ),
                            ( (Weeks- MAX([Index] )* 7 ) + 1,
                            DAY
                        ),
                        7,
                        DAY
                    )
                )
        )
    )

     

    Best regards,
    Lionel Chen

    If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.

     

    • littlemojopuppy's avatar
      littlemojopuppy
      Community Champion

      Tried it out...did not work.  The problem is that using MAX(Index) only looks at the week/index value furthest in time.  I need to look at each individual 7 day period starting with today up to the week/index.  Really could use looping but that doesn't seem like its' possible.

      • v-lionel-msft's avatar
        v-lionel-msft
        Community Support

        Hi littlemojopuppy ,

         

        Or like this?

        Users Returning Within 42 Days = 
        VAR Weeks = 5
        RETURN
        COUNTROWS (
                CALCULATETABLE (
                    VALUES ( IdentityLog[IdentityId] ),
                    
                    CALCULATETABLE (
                        VALUES ( IdentityLog[IdentityId] ),
                        // 0
                        DATESINPERIOD ( 
                            'Calendar'[Date],
                            DATEADD ( LASTDATE ( 'Calendar'[Date] ), ( (Weeks-0 )* 7 ) + 1, DAY ),
                            7, DAY
                        ),
                        // 1
                        DATESINPERIOD ( 
                            'Calendar'[Date],
                            DATEADD ( LASTDATE ( 'Calendar'[Date] ), ( (Weeks-1 )* 7 ) + 1, DAY ),
                            7, DAY
                        ),
                        // 2
                        DATESINPERIOD ( 
                            'Calendar'[Date],
                            DATEADD ( LASTDATE ( 'Calendar'[Date] ), ( (Weeks-2 )* 7 ) + 1, DAY ),
                            7, DAY
                        ),
                        //3
                        DATESINPERIOD ( 
                            'Calendar'[Date],
                            DATEADD ( LASTDATE ( 'Calendar'[Date] ), ( (Weeks-3 )* 7 ) + 1, DAY ),
                            7, DAY
                        ),
                        // 4
                        DATESINPERIOD ( 
                            'Calendar'[Date],
                            DATEADD ( LASTDATE ( 'Calendar'[Date] ), ( (Weeks-4 )* 7 ) + 1, DAY ),
                            7, DAY
                        ),
                         // 5
                        DATESINPERIOD ( 
                            'Calendar'[Date],
                            DATEADD ( LASTDATE ( 'Calendar'[Date] ), ( (Weeks-5 )* 7 ) + 1, DAY ),
                            7, DAY
                        ),
                        //5
                         DATESINPERIOD ( 
                            'Calendar'[Date],
                            DATEADD ( LASTDATE ( 'Calendar'[Date] ), ( (Weeks-5 )* 7 ) + 1, DAY ),
                            7, DAY
                        )
                    )
                )
        )

        If you need to use the CALCULATETABLE() function, it seems that you can only list each filter, you can not list it in a loop.

         

        Best regards,
        Lionel Chen

        If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.