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
jcecil2
Helper I
Helper I

Compare the values in a column by row group

Hello, 

I am attempting to find the number of members gained and members lost by hour for each group in the table below:

 

DATEHOURGROUPMEMBERS
2018-01-0101A, B
2018-01-0111A, C
2018-01-0121A, D, E
2018-01-0131D, F
2018-01-0102A
2018-01-0112C
2018-01-0122C, D
2018-01-0132D, E, F

 

My output would be:

DATEHOURGROUPMEMBERSMEMBERS GAINEDMEMBERS LOST
2018-01-0101A, BNULLNULL
2018-01-0111A, C11
2018-01-0121A, D, E21
2018-01-0131D, F12
2018-01-0102ANULLNULL
2018-01-0112C11
2018-01-0122C, D10
2018-01-0132D, E, F21

 

I'm not entirely sure this is possible in DAX, as it would require parsing the string in the members column. However, I could have the table set up to where each member has their own row. The table would look like this:

 

DATEHOURGROUPMEMBER
2018-01-0101A
2018-01-0101B
2018-01-0111A
2018-01-0111C
2018-01-0121A
2018-01-0121D
2018-01-0121E

 

I am not sure the best way to approach this problem. Any suggestions would be greatly appreciated. 

Thank you,

 

1 REPLY 1
sturlaws
Resident Rockstar
Resident Rockstar

Hi, @jcecil2,

 

I can't see any ways of solving this with the members concatenated into a string, although it might be possible in power query(but outside of what I'm capable of doing). When there is a row for each member, there are a couple of possibilities.


If you can do this by columns, meaning it does not have to be dynamic with respect to filtering in a report, you can use something like this to calculate lost members with dax:

Lost =
VAR _group =
    CALCULATE ( SELECTEDVALUE ( 'Table'[GROUP] ) )
VAR _hour =
    CALCULATE ( SELECTEDVALUE ( 'Table'[HOUR] ) )
VAR _date =
    IF ( _hour = 24; DATEADD ( 'Table'[DATE]; 1; DAY ); 'Table'[DATE] )
VAR _hourNext =
    IF ( _hour = 24; 0; _hour + 1 )
VAR _member =
    CALCULATE ( SELECTEDVALUE ( 'Table'[MEMBERS] ) )
RETURN
    IF (
        COUNTROWS (
            FILTER (
                ALL ( 'Table' );
                'Table'[MEMBERS] = _member
                    && 'Table'[GROUP] = _group
                    && _hourNext = 'Table'[HOUR]
            )
        ) < 1;
        1;
        0
    )

and corresponding for the gained members. Note that the lost members are calculated looking forward in time, while gained members are calculated looking backwards in time. This means that they are shifted 1 hour, and you will have to come up with some tricks if you want to show it like your desired outcome.

 

Something similar can also be handled by Power Query. Not that many steps to it, but I'll share a file instead of describing the steps: .pbix 

 

For both options, the begining and the end of the dataset have to be handled. You can handle it dynamically or you can hardcode it.

 

If the input data has one row for each member, how should it be displayed? With all members concatenated into 1 string as before? This will have to be handled in a different table, or keeping a column with those values.

 

Now, if you have to do this dynamically and responsive to filters and slicers, you have to do it as a measure. Then you should take a look at the new and returning customer pattern over at daxpatterns.com: https://www.daxpatterns.com/new-and-returning-customers/


Cheers,
Sturla

If this post helps, then please consider Accepting it as the solution. Kudos are nice too.

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.