2016-11-16 2 views
0

Я пытаюсь написать рассчитанную DAX меру, которая использует вложенные агрегаты для вычисления на основе пользовательского контекста запроса, и мне трудно понять, как применить контекст запроса к внутренняя агрегация, а также внешняя. Упрощенная структура моих данных таблицы ниже, где каждая продажа запись представляет собой продажу одного виджета на одного пользователя к другому для данной цены продажи:DAX Вложенные агрегированные контексты/фильтры

Schema

enter image description here

И некоторые примеры данных :

Data

enter image description here

Ниже приведен расчетный запрос измерения, который в основном пытается рассчитать в среднем, насколько хороша сделка, которую каждый покупатель получает за свои покупки. Он делает это, выполняя следующие расчеты:

1) Внутренний «Рассчитать»: для каждой записи продажи. Рассчитать среднюю цену данный продавец продает свои виджеты для (потенциально фильтруется).

2) Outer 'Calculate': для каждой записи продажи. Рассчитайте среднее значение цены за вычетом суммы, рассчитанной в # 1, в основном предоставляя дифференциал фактических и ожидаемых объемов продаж.

Avg Actual/Expected Differential := 
    CALCULATE (
     AVERAGEX (
      Sale, 
      Sale[Price] 
       - CALCULATE (AVERAGEX (Sale, Sale[Price]), ALLEXCEPT (Sale, Sale[Seller])) 
     ) 
    ) 

Эта формула работает в стандартном случае, когда не применяются фильтры запросов, кроме фильтров, связанных с пользователем. Например, фактические и ожидаемые продажи Dale:

  • Продажа у Ларри за 2 доллара, где средняя продажа Ларри составляет 3,5 доллара. Дифференциал = - $ 1,5
  • Продажа от Боба за 5 долларов, где средняя продажа Боба составляет 3 доллара. Дифференциал = $ 2
  • Продажа от Джона за 4 доллара, где средняя продажа Джона составляет 4 доллара. Дифференциал = $ 0

Таким образом, средний фактический/ожидаемый дифференциал составляет $ .5/3 = $ .17.

Проблема, с которой я столкнулся, заключается в применении фильтра запросов на поле IsCashSale и с этим фильтром применимы как к внутренним, так и к внешним функциям Calculate.

Например, если я хочу, чтобы фильтровать как внутренний и внешний, чтобы включать только продажа записей, которые имеют истинное IsCashSale значение можно создать соответствующий фильтр в пользовательском интерфейсе и внешний Calculate функцию фильтруется надлежащим образом, однако, когда внутренний Calculate он удаляет этот фильтр по IsCashSale в результате функции AllExcept, которая удаляет фильтры из всех столбцов, кроме поля Seller.

Я попытался включая Sale[IsCashSale] сумму в списке AllExcept поля, однако из-за текущий контекст строки, это включает в себя только все записи, которые имеют один и то же IsCashSale значения суммы в качестве текущей записи внутреннего цикла «Рассчитать». Это вызывает сценарий, при котором фильтр не был применен к IsCashSale, чтобы быть неправильным.

Я считаю, что я могу найти способ передать выбранные значения от внешнего Calculate к внутреннему? Если я могу это сделать, я могу включить эти значения в качестве фильтров на внутреннем Calculate. Есть ли способ использовать что-то вроде функций Earlier или AllSelected для этого? Или есть другой способ сделать то, что я пытаюсь сделать? Благодаря!

+0

Примечание: Я Мессинг с 'функцией KeepFilters', которая появляется, чтобы получить меня очень близко: ' Среднее Actual/Ожидаемое Дифференциал: = CALCULATE ( \t AVERAGEX (Продажа, \t \t Продажа [Цена] \t \t - \t \t CALCULATE ( \t \t \t AVERAGEX ( \t \t \t \t Продажа, \t \t \t \t Продажа [Цена]), \t \t \t \t ALLEXCEPT (Продажа, Продажа [Продавец]), \t \t \t \t KEEPFILTERS (VALUES (Продажа [IsCashSale])) \t \t) \t) ) ' В этом случае значение, когда я применил' IsCashSale' фильтр является правильным, и 3 из 5 значений являются правильными, когда не применяются ни один фильтр. –

+0

Это все еще не на 100% правильно, но это может быть начало. Может кто-нибудь объяснить, что там происходит? –

+0

Nevermind, кажется, что удаление функции KeepFilters, но оставление вызова «Ценности» приводит к тому же. Ничего особенного в 'KeepFilters' –

ответ

0

Хорошо, я думаю, что нашел решение, но это немного запутанно. Это требует разрыва суммы отдельных покупок покупателем от средних продаж для каждого продавца. Я считаю, что большая разница в том, что с помощью определения VALUES(Sale[Seller]) набора, а не просто Sale это позволяет нам сохранить то, что фильтры на месте на IsCashSale поле во внешнем Calculate функции:

Avg Actual/Expected Differential:=CALCULATE(
(
    SUM(Sale[Price]) --Sum of Buyer purchases 
    - CALCULATE ( 
     SUMX( 
      VALUES(Sale[Seller]) --Calculate for each unique Seller 
      ,CALCULATE(COUNTROWS(Sale)) --Need to multiply by number of purchases from this particular Seller 
      * CALCULATE (--Get Seller's average sale price 
       AVERAGEX (Sale, Sale[Price]) 
       ,ALLEXCEPT(Sale, Sale[Seller], Sale[IsCashSale]) 
      ) 
     ) 
    ) 
) 
/COUNTROWS(Sale) --Divide by total number of sales to get average 

)

0

Как насчет использования функции ISFILTERED?

Avg Actual/Expected Differential 2:=IF(ISFILTERED([IsCashSale]),CALCULATE (
    AVERAGEX (
     Sale, 
     Sale[Price] 
      - CALCULATE (AVERAGEX (Sale, Sale[Price]), ALLEXCEPT (Sale, Sale[Seller],Sale[IsCashSak])) 
    ) 
), 
CALCULATE (
    AVERAGEX (
     Sale, 
     Sale[Price] 
      - CALCULATE (AVERAGEX (Sale, Sale[Price]), ALLEXCEPT (Sale, Sale[Seller])) 
    ) 
) 
) 

Теперь вы увидите результаты, как это, когда колонна IsCashSale фильтруется, и когда он не фильтруется он будет вести себя оригинальный способ.

Это те результаты, которые вы хотели?

+----+--------+-------+-----------+--------------+------------------------------------+ 
| Id | Seller | Buyer | IsCashSak | Sum of Price | Avg Actual/Expected Differential 2 | 
+----+--------+-------+-----------+--------------+------------------------------------+ 
| 1 | Bob | John | TRUE  |   1 |         0 | 
| 2 | John | Bob | TRUE  |   2 |         -1 | 
| 3 | Dale | Bob | TRUE  |   1 |        -0.5 | 
| 8 | Sue | Bob | TRUE  |   3 |         0 | 
| 10 | John | Dale | TRUE  |   4 |         1 | 
| 13 | Dale | Kelly | TRUE  |   2 |        0.5 | 
+----+--------+-------+-----------+--------------+------------------------------------+ 
+0

Да, это сработает, но можно ли поместить логику' If' внутри списка фильтров внутреннего расчета? В противном случае запись выражения для охвата схемы, где может быть более одного отфильтрованного измерения, становится довольно огромной. –

+0

Вы правы, я тоже не большой поклонник длинных формул, поэтому я не решался поделиться этим ответом. – RedVII

+0

Это только что пришло ко мне, как насчет того, чтобы не использовать вложенные КАЛЬКУЛЯЦИИ в первую очередь? Как насчет разделения функций CALCULATE, а затем введите [IsCashSale] в ALLEXCEPT второго вычисления?Эта формула дает те же результаты: Avg Фактическое/расчетное дифференциальной 3: = CALCULATE ( AVERAGEX ( Продажи, Продажи [Цена] ) ) - CALCULATE (AVERAGEX (Продажа, Продажа [Цена]), ALLEXCEPT (Продажа , Продажа [Продавец] Продажа [IsCashSale])) – RedVII

Смежные вопросы