Как написать оптимизированную меру DAX для агрегирования значений по двум группам по атрибутам - PullRequest
1 голос
/ 24 марта 2019

Что если нам нужно агрегировать (Sum) группы значений по двум атрибутам в DAX.Я написал следующую меру с помощью функции Summarize, но она очень медленная.

Reorder :=
SUMX (
    SUMMARIZE (
        TableA,
        TableA[ProdID],
        TableA[CustID],
        "ReordersCount",
        VAR VarInvoiceCount =
            SUM ( TableA[InvoiceCount] )
        RETURN
            IF ( VarInvoiceCount > 0, VarInvoiceCount - 1, 0 )
    ),
    [ReordersCount]
) 

Я также искал SummarizeColumns, но он не работает в отчете, когда я применяю другие атрибуты срезы.Может быть, я что-то упустил?Ищем оптимизированное решение.Большое спасибо заранее.

1 Ответ

1 голос
/ 24 марта 2019

Рассмотрим следующий подход:

Сначала создайте показатель для общего количества счетов:

Total Invoice Count = SUM(TableA[InvoiceCount])

Во-вторых, создайте меру для подсчета количества первых счетов-фактур, представляющих собой просто число уникальных комбинаций продукт-клиент в вашей таблице:

First Invoice Count =
COUNTROWS ( SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ) )

Наконец, желаемый результат - это просто разница этих двух показателей:

Reorder Count = [Total Invoice Count] - [First Invoice Count]

Формула будет правильно реагировать на все слайсеры и фильтры и должна быть очень быстрой, потому что нет вложенных итерационных циклов, таких как SUMX (SUMMARIZE ()), нет контекстных переходов и обратных вызовов внутри циклов, вызванных использованием IF заявления (это немного сложная тема).

Конечно, вы можете поместить все в одну меру, используя переменные:

Reorder Count = 
VAR Total_Invoice_Count = SUM(TableA[InvoiceCount])
VAR First_Invoice_Count = COUNTROWS ( SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ) )
VAR Reorder_Count = Total_Invoice_Count - First_Invoice_Count
RETURN Reorder_Count

хотя лично я предпочитаю разбивать меры, потому что отдельные меры легче понять и отладить, и они могут иметь свое собственное использование.

Приведенный выше подход очень эффективен, но он предполагает, что ТаблицаA содержит только действительные ордера. Если он также имеет отмены, возвраты и т. Д., Которые могут иметь нулевое или отрицательное число счетов, вам придется использовать менее эффективный подход, например:

Reorder Count =
SUMX (
    SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ),
    VAR Reorder_Count = CALCULATE ( SUM ( TableA[Invoice] ) ) - 1
    RETURN
        IF ( Reorder_Count > 0, Reorder_Count, 0 )
)

или

Reorder Count =
SUMX (
    SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ),
    MAX(CALCULATE ( SUM ( TableA[Invoice] ) ) - 1, 0) )

Тем не менее, они должны быть еще быстрее, чем ваша первоначальная формула.

...