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

Earn a 50% discount on the DP-600 certification exam by completing the Fabric 30 Days to Learn It challenge.

Reply
AndersDonker
Helper I
Helper I

Perform a double aggregate with DAX

Dear forum,

 

i'm struggling with a solution which I expect to be easy but can't seem to wrap my head around within DAX.

 

My desired output is to have a dynamic calculation that can be filtered in PowerBI with the regular relationships and underlying data but is aggregated twice.

 

The first aggregate is to calculate how many products a single customer has taken, given a specific timeframe and possible other filters.

The second aggregate is to group these customers into clusters to have an output similar to the following:

 

Desired output:

# Amount of customers# Amount of products taken
25.4210 Products
49.5721 to 3 Products
12.4514 to 6 Products
6.0217 to 9 Products
3.21210 to 12 Products
1.421> 12 Products

 

How do I generate a measure (and maybe some additional columns) to create such an output?

I have added an example dataset to this topic to experiment with.

 

In a second question, i would like to also be able to aggregate the data into years since a customer has entered vs the product taken date. An example of this output would be:

 

# amount of products takenYears since customer start
15030
2321
242
103

 

Datamodel example:

AndersDonker_1-1704966258699.png

 

Example data

 

CustomerIDCustomer_Since
A1-1-2021
B1-2-2021
C1-2-2022
D1-6-2022
E1-8-2022
F1-10-2022
G1-12-2023

 

 

Example Product data:

 

IDProductIDCustomerIDProduct_Date
11A3-1-2021
22A12-1-2023
33B1-5-2021
43B1-10-2021
56C1-1-2024
610E1-6-2023
713E1-8-2023
815E1-10-2023
918E1-12-2022
101F1-6-2023
1121F1-8-2023

 

 

Note: the desired output is just fictive, it does not correspond with the provided example data.

 

The link to the example PBIX dataset:

Example-Set.pbix

 

 

 

 

 

 

 

 

 

 

2 ACCEPTED SOLUTIONS

Hi @v-nuoc-msft,

 

i have added a note and i added the pbix file. 

View solution in original post

ERD
Super User
Super User

Hi @AndersDonker ,

The answer to your first question:

1. You need a new table with categories and a Date table:

ERD_0-1705316914043.png

ERD_2-1705322488632.png

2. Measures:

products amt = DISTINCTCOUNT(Product2[ProductID])
customers amt = 
VAR c_category = SELECTEDVALUE ( Categories[Amt category] )
VAR t =
    FILTER (
        ADDCOLUMNS (
            VALUES ( Customer1[CustomerID] ),
            "@products", [products amt],
            "@category",
                VAR amt = [products amt]
                RETURN
                    CALCULATE (
                        MAX ( Categories[Amt category] ),
                        amt <= Categories[MaxValue],
                        amt >= Categories[MinValue]
                    )
        ),
        [@category] = c_category
    )
RETURN
    COUNTAX ( t, [CustomerID] )

ERD_1-1705316936670.png

The answer for your second question:

1. You need a new table with possible years:

ERD_3-1705322549920.png

2. Measure:

products taken = 
VAR customers = SUMMARIZE ( Customer1, Customer1[CustomerID], Customer1[Date_Since] )
VAR customers_with_dt_from =
    SELECTCOLUMNS (
        GENERATE (
            customers,
            VAR dt = [Date_Since]
            VAR m = MONTH ( dt )
            VAR d = DAY ( dt )
            RETURN
                FILTER (
                    GENERATESERIES ( dt, DATE ( YEAR ( TODAY () ), m, d ), 1 ),
                    DAY ( [Value] ) = d && MONTH ( [Value] ) = m
                )
        ),
        "CustomerID", [CustomerID],
        "dt_from", [Value]
    )
VAR customers_with_date_to =
    ADDCOLUMNS (
        customers_with_dt_from,
        "dt_to",
            VAR dt = [dt_from]
            VAR dates = DATESINPERIOD ( 'Date'[Date], dt, 12, MONTH )
            RETURN
                MAXX ( dates, [Date] )
    )
VAR customers_with_products =
    ADDCOLUMNS (
        customers_with_date_to,
        "years_since",
            VAR _customer = [CustomerID]
            VAR min_dt = MINX ( FILTER ( customers_with_date_to, [CustomerID] = _customer ), [dt_from] )
            VAR max_dt = [dt_to]
            RETURN
                DATEDIFF ( min_dt, max_dt, YEAR ),
        "products",
            VAR c_dt_from = [dt_from]
            VAR c_dt_to = [dt_to]
            RETURN
                CALCULATE (
                    [products amt],
                    Product2[Product_Date] >= c_dt_from,
                    Product2[Product_Date] <= c_dt_to
                )
    )
VAR _years = SELECTEDVALUE( Years[Years] )
VAR result = SUMX( FILTER( customers_with_products, [years_since] = _years), [products])
RETURN
    result

 

ERD_4-1705322593882.png

 

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

Check out my latest demo report in the data story gallery.

Stand with Ukraine!


Here are official ways you can support Ukraine financially (accounts with multiple currencies):
1) Support the Armed Forces of Ukraine: https://bank.gov.ua/ua/about/support-the-armed-forces
2) Come Back Alive foundation: https://www.comebackalive.in.ua/

Thank you!

View solution in original post

5 REPLIES 5
ERD
Super User
Super User

Hi @AndersDonker ,

The answer to your first question:

1. You need a new table with categories and a Date table:

ERD_0-1705316914043.png

ERD_2-1705322488632.png

2. Measures:

products amt = DISTINCTCOUNT(Product2[ProductID])
customers amt = 
VAR c_category = SELECTEDVALUE ( Categories[Amt category] )
VAR t =
    FILTER (
        ADDCOLUMNS (
            VALUES ( Customer1[CustomerID] ),
            "@products", [products amt],
            "@category",
                VAR amt = [products amt]
                RETURN
                    CALCULATE (
                        MAX ( Categories[Amt category] ),
                        amt <= Categories[MaxValue],
                        amt >= Categories[MinValue]
                    )
        ),
        [@category] = c_category
    )
RETURN
    COUNTAX ( t, [CustomerID] )

ERD_1-1705316936670.png

The answer for your second question:

1. You need a new table with possible years:

ERD_3-1705322549920.png

2. Measure:

products taken = 
VAR customers = SUMMARIZE ( Customer1, Customer1[CustomerID], Customer1[Date_Since] )
VAR customers_with_dt_from =
    SELECTCOLUMNS (
        GENERATE (
            customers,
            VAR dt = [Date_Since]
            VAR m = MONTH ( dt )
            VAR d = DAY ( dt )
            RETURN
                FILTER (
                    GENERATESERIES ( dt, DATE ( YEAR ( TODAY () ), m, d ), 1 ),
                    DAY ( [Value] ) = d && MONTH ( [Value] ) = m
                )
        ),
        "CustomerID", [CustomerID],
        "dt_from", [Value]
    )
VAR customers_with_date_to =
    ADDCOLUMNS (
        customers_with_dt_from,
        "dt_to",
            VAR dt = [dt_from]
            VAR dates = DATESINPERIOD ( 'Date'[Date], dt, 12, MONTH )
            RETURN
                MAXX ( dates, [Date] )
    )
VAR customers_with_products =
    ADDCOLUMNS (
        customers_with_date_to,
        "years_since",
            VAR _customer = [CustomerID]
            VAR min_dt = MINX ( FILTER ( customers_with_date_to, [CustomerID] = _customer ), [dt_from] )
            VAR max_dt = [dt_to]
            RETURN
                DATEDIFF ( min_dt, max_dt, YEAR ),
        "products",
            VAR c_dt_from = [dt_from]
            VAR c_dt_to = [dt_to]
            RETURN
                CALCULATE (
                    [products amt],
                    Product2[Product_Date] >= c_dt_from,
                    Product2[Product_Date] <= c_dt_to
                )
    )
VAR _years = SELECTEDVALUE( Years[Years] )
VAR result = SUMX( FILTER( customers_with_products, [years_since] = _years), [products])
RETURN
    result

 

ERD_4-1705322593882.png

 

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

Check out my latest demo report in the data story gallery.

Stand with Ukraine!


Here are official ways you can support Ukraine financially (accounts with multiple currencies):
1) Support the Armed Forces of Ukraine: https://bank.gov.ua/ua/about/support-the-armed-forces
2) Come Back Alive foundation: https://www.comebackalive.in.ua/

Thank you!

Hi @ERD, now that i am trying to implement your solution regarding the customer amt into my existing model I seem to have an issue with the VALUES() part of the solution. I would like to (pre)filter the customers based on their date_since. Is there an option to extend the solution with this feature?

customers amt = 
VAR c_category = SELECTEDVALUE ( Categories[Amt category] )
VAR t =
    FILTER (
        ADDCOLUMNS (
            VALUES ( Customer1[CustomerID] ),
            "@products", [products amt],
            "@category",
                VAR amt = [products amt]
                RETURN
                    CALCULATE (
                        MAX ( Categories[Amt category] ),
                        amt <= Categories[MaxValue],
                        amt >= Categories[MinValue]
                    )
        ),
        [@category] = c_category
    )
RETURN
    COUNTAX ( t, [CustomerID] )

 

 

 

 

 

On line 6 you use the VALUES ( Customer1[CustomerID] ) solution. Is it possible to extend this part of the code to filter the customers we process in the measure, based on date?



For example: if i choose the year 2021, I would like to see that the measure returns just 2 customers (A and B) and for both produce a 1 as a result in the category 1 to 3 products. I don't want to see C D E F G as customers with 0 products.


 

AndersDonker_0-1705935726107.png

I am thinking of something like:
FILTER(VALUES(Customer1[CustomerID]),  with date between min and maxdate of the year) but that obiously does not work. 🙂

 

 

 



Amazing! many thanks for your elaborate solution to the problem! I now understand why I was unable to produce the results myself. I need to increase my understanding of DAX to a more indepth level to grasp these type of solutions!

 

Thanks!

v-nuoc-msft
Community Support
Community Support

Hi @AndersDonker

 

I can't seem to understand your desired outcome. Can you provide your PBIX file? So that I can help you better. Please remove any sensitive data in advance.

 

Regards,

Nono Chen

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

Hi @v-nuoc-msft,

 

i have added a note and i added the pbix file. 

Helpful resources

Announcements
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.

Top Solution Authors