SUM и SUMX; В чем разница двух функций DAX в Power BI?

Tags: DAX, Power BI

Sum и Sumx - это функции, которые часто создаются для введения в заблуждение для многих пользователей Power BI. Поскольку обе функции выполняют агрегацию, кажется немного запутанным, какова фактическая разница между ними двумя. Есть много сообщений в блогах и статей о каждой из этих функции. Сегодня мы объясним разницу с простыми демонстрационными примерами.

SUM: агрегатная функция

SUM - простая агрегатная функция. Она суммирует значение, основанное на контексте фильтра. Например, если у меня есть такая мера, как:

 

1

Sum of Sales = SUM(FactInternetSales[SalesAmount])

Эта мера просто вычисляет суммарное значение SalesAmount по всей таблице фактов, когда фильтр не выбран. И если у нас где-нибудь в нашей визуализации есть фильтр, тогда он будет вычислять сумму отфильтрованного контекста;

 

Все остальные агрегатные функции также работают одинаково; Average, Min, Max, Count и т. д. Теперь давайте посмотрим, когда функции SUM не совпадают.

 

SUMX: часть выражения

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

 

Расчет маржи: SalesAmount - TotalProductCost

 

Но вы не можете написать такую меру, как показано ниже:

 

Фактически, когда вы начинаете писать эту меру, вы даже не получаете DAX intelligence для второй части выражения:

DAX intelligence не показывает столбец TotalProductCost из таблицы FactInternetSales, но столбец определенно находится в таблице. Интеллект в DAX всегда надежный, если он не позволяет вам что-то писать где-то, это означает, что на основе структуры вашего выражения или функций, которые вы использовали, вероятно, это не место для написания. Так почему вы не можете написать такое простую инструкцию?

 

Потому что SUM принимает только имя столбца в качестве входного. Вот структура функции SUM;

 

Как видите, ввод - это только одно имя столбца. Это не может быть один столбец минус другой; это означает выражение. Итак, каков способ сделать это? Один из способов - использовать несколько функций суммы, например, под кодом:

 

Sum of Margin = SUM(FactInternetSales[SalesAmount])-SUM(FactInternetSales[TotalProductCost])

 

И это сработает. Тем не менее, для длинных выражений этот способ написания станет едва читаемым. Если вы добавите одну сумму перед каждым именем столбца, вы можете получить следующие выражения:

 

4

5

6

7

8

9

10

A measure with few SUMs =

if((SUM(FactInternetSales[SalesAmount])

-SUM(FactInternetSales[TotalProductCost]))

/SUM(FactInternetSales[OrderQuantity])

>SUM(FactInternetSales[ExtendedAmount])

,SUM(FactInternetSales[ExtendedAmount])

-SUM(FactInternetSales[SalesAmount])

,SUM(FactInternetSales[OrderQuantity])

*(SUM(FactInternetSales[UnitPrice])

-SUM(FactInternetSales[UnitPriceDiscountPct])))

 

Выглядит страшно, не так ли? Ну, есть другой способ; используйте SUMX. SUMX - сумма выражения, X в конце этой функции - для eXpression. Эта функция дает вам сумму любого выражения. Вот способ его использования:

 

SumX(<table name>,<expression>)

 

Для работы SUMX вам необходимо указать имя таблицы. Когда вы используете SUM, вам не нужно имя таблицы, потому что один столбец принадлежит только одной таблице. Но когда вы используете SUMX, вы можете написать выражение, которое использует столбцы из других таблиц. В примере для Margin оба столбца поступают из одной таблицы; FactInternetSales. Итак, наше выражение будет таким:



1

2

3

4

Sum of Margin = SUMX(

FactInternetSales,

FactInternetSales[SalesAmount]-FactInternetSales[TotalProductCost]

)

SUMX - это сумма выражения, но SUM просто суммирует значения одного столбца.

 

SUMX - это функция итератора

Как SUMX за сценой делает расчет? SUMX будет проходить через каждую запись таблицы ввода и запускать выражение для этой записи, он сохраняет результат этого во временную память.

 

По окончании разбора таблицы и вычисления всех значений для каждого отдельного столбца она суммирует их все вместе, поскольку SUMx освобождает временную память и визуализирует результат;

 

Из-за этого характера ITERATION функции SUMX он также называется функцией- итератором. Другие функции-итераторыа: AverageX, MinX, MAXX, CountaX и т. д.

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

Важное понимание SUMX заключается в том, что SUMX использует память (временно, но все еще использует память) для расчета. Другой важный вывод состоит в том, что он вычисляет значения по строкам. Если вы запустите SUMX на очень большой таблице со сложным выражением, вам, вероятно, придется немного подождать, пока результаты не пройдут.

Тайное сокровище SUMX; Вход в таблицу

Пример, который вы видели до сих пор о SUMX, был простым, и вы даже могли писать его без SUMX (помните, как мы это делали с несколькими функциями SUM). Но тайное сокровище использования функции SUMX - это не просто гибкость выражения, но и гибкость при вводе таблицы.

Предположим, вы хотите рассчитать общую маржу в выражении. Как мы это сделаем? Ну, вы можете сказать, что мы просто используем ту же инструкцию SUMX, которую мы использовали до сих пор, что дает нам следующий результат;

 

Но выражение выше не всегда дает вам общую маржу. Если вы фрагментируете его по столбцу, результат будет следующий;

 

Контекст фильтра (или, скажем, любые фильтры визуального) повлияет на результат вычисления. Итак, когда вы смотрите категорию образования бакалавров, сумма Margin для этого не является общей маржой, это просто сумма маржи для этой категории.

ALL - интересная функция, о которой мы напишем позже. Тем временем, если мы используем функцию ALL, чтобы получить всю таблицу независимо от контекста фильтра, то вот как будет выглядеть наше выражение и результат:



1

2

3

4

Total Margin = SUMX(

ALL(FactInternetSales),

FactInternetSales[SalesAmount]-FactInternetSales[TotalProductCost]

)

Как это работает? ALL - это функция, которая возвращает таблицу как результат. SUMX - это функция, которая получает таблицу как входную. Поэтому они могут прекрасно работать друг с другом! ALL может быть таблицей ввода функции SUMX. Вложение или каскадное расположение функций и таблиц по отношению друг к другу - это то, что происходит очень часто в DAX. Потому что ALL - это функция, которая передает всю таблицу независимо от контекста фильтра, поэтому мы получаем полную таблицу FactInternetSales без фильтров, и результатом будет всегда общая маржа.

Вы можете подумать, где может пригодится использование такой вещи? Ну, вы можете использовать его для расчета процентной доли маржи для каждой категории образования. Вот как это работает:

Любая TABLE может служить входными данными для SUMX

Это не просто функция ALL, которая может быть входом для SUMX, вы также можете использовать любые другие функции, которые возвращают таблицу, или любые другие таблицы в качестве входа для SUMX. Например, приведенное ниже выражение дает нам Отфильтрованный результат таблицы FactInternetSales, когда категорией Education является “High School”;

 

В этом примере функция FILTER, используемая в качестве входных  данных для SUMX, дает нам результат вычисления только в отфильтрованном наборе данных.



1

2

3

4

5

6

7

Sum of Margin for High School = SUMX(

FILTER(

FactInternetSales,

RELATED(DimCustomer[EnglishEducation])="High School"

),

FactInternetSales[SalesAmount]-FactInternetSales[TotalProductCost]

)

Это можно сделать и с другими функциями. Здесь, например, мы использовали функцию CalculateTable для фильтрации:

 

1

2

3

4

5

6

Sum of Sales by Customer = SUMX(

CALCULATETABLE(

FactInternetSales,

DimCustomer[EnglishEducation]="High School"

),

FactInternetSales[SalesAmount]-FactInternetSales[TotalProductCost])

Вот результат:

 

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

Существует функция, которая может действовать более общим образом, чем SUMX, называемый Calculate. Мы напишем об этом в другой статье.

Резюме

Sum и SumX - это функции, рассчитывающие агрегацию. Однако SUMX вычисляет агрегацию по выражению, разрешенному из таблицы, которая также может быть динамически рассчитана. SUMX - это общая и мощная функция, поэтому мы часто используем это в DAX. Следует помнить, что SUMX, как и любые другие функции итератора, потребляет временное хранилище памяти и выполняет вычисление по одной строке за раз, а затем агрегирует его.



No Comments

Add a Comment