DAX. Логика табличного фильтра в мере, Хочу понять в точности логику табличного фильтра в мере, заданной с помощью функции CALCULATE и изменённой активной связью с помощью функции USERELATIONSHIP
Данная мера использована в матрице, где в строки выведены бренды - скрин
Объясню, как я понимаю логику работы этой меры. 1. Таблица Sales фильтруется по Brand, далее фильтруется по количеству Quantity больше 1. 2. Отфильтрованная таблица поступает как условие фильтра для меры [Sales Amount] И тут у меня вопрос: правильно ли я понимаю, что внешний фильтр по брендам не действует на меру [Sales Amount], так как таблица Sales уже отфильтрована по Brand, а так как таблица Sales расширенная по отношению к таблице Product, то включает связанный столбец Product[Brand] ?
выдаёт пустые значения. Мера используется в матрице, где в строки выведены годы - скрин1
Ведь тут же по идее та же логика. 1. Таблица Sales связана с таблицей 'Date' по дате доставки. 2. Таблица Sales, связанная с таблицей 'Date' по дате доставки, фильтруется по году из внешнего контекста фильтра. 3. Отфильтрованная таблица Sales поступает как условие фильтра для меры [Sales Amount] Получается, что внешний фильтр по годам не действует на меру [Sales Amount], так как таблица Sales расширенная по отношению к таблице 'Date' и включает годы (годы доставки).
В книге "Подробное руководство по DAX" пустые значения меры объяснены тем, что таблица с привязкой к дате заказа пытается отфильтровать таблицу с привязкой к дате доставки, но откуда вдруг появилась эта таблица с привязкой к дате заказа, когда в формуле задана привязка к дате доставки, я не понимаю.
Дмитрий Никитин, добрый день. Я конечно когда-то читал умные книжки, но бол-во уже позабыл, поэтому я так, своими словами попробую. 1. CALCULATE - самая мощная функция, которая позволяет менять контексты фильтров с помощью других вложенных функций. То же и про CALCULATETABLE(), только она не значение дает, а таблицу, которую дальше нужно считать.
Цитата
Дмитрий Никитин написал: Если так, тогда я не понимаю, почему другая мера:
вот то, что Вы написали, честно говоря, бессмыслица какая-то. Если цель стоит посчитать продажи по дате доставки, то тогда достаточно написать:
Теперь объясняю, почему не срабатывает Ваш вариант. Внутри CALCULATETABLE() вы используете USERELATIONSHIP() и изменили связь. По сути вы сделали таблицу, где есть столбец "Quantity" и "Delivery Date" в формате даты. Далее Вы хотите посчитать сумму по данной измененной таблице внутри CALCULATE(). Тут возникает одно НО. В функцию CALCULATE() не передан модификатор USERELATIONSHIP(), она только внутри CALCULATETABLE() и соответственно CALCULATE() продолжает считать по текущей активной связи с датой "OrderDataKey". А теперь обратите внимание, что в этих двух столбцах форматы дат абсолютно разные "OrderDataKey" и "Delivery Date". Поэтому CALCULATE() и выдает BLANK(), т.к. форматы дат абсолютно не совпадают. Если продолжить Вашу логику рассуждения, то Вам нужно было бы написать так:
написал: Тут возникает одно НО. В функцию CALCULATE() не передан модификатор USERELATIONSHIP(), она только внутри CALCULATETABLE() и соответственно CALCULATE() продолжает считать по текущей активной связи с датой "OrderDataKey".
Я почти начал понимать вашу логику, но тут вспомнил изначальный вопрос. В мере:
внешний фильтр по Brand не действует на меру [Sales Amount] - скрин ?
Таблица Sales фильтруется по внутреннему фильтру Quantity и внешнему Brand и поступает как внутренний фильтр для меры [Sales Amount]. Внешний же фильтр по Brand на меру [Sales Amount] не действует, потому что таблица Sales - расширенная таблица относительно таблицы Product, в которой присутствует столбец Product[Brand], а значит таблица Sales содержит этот столбец. Получается, что таблица Sales, уже отфильтрованная по Brand, перебивает внешний фильтр по Brand.
На конечный результат эти тонкости не влияют, цифры получились бы одинаковые и в том случае, если бы [Sales Amount] фильтровалась внешним фильтром по Brand - внешний фильтр совпал бы с внутренним и на вычисления не повлиял.
написал: CALCULATE() продолжает считать по текущей активной связи с датой "OrderDataKey"
Если я прав относительно меры [Multiple Sales], значит не должен считать по текущей активной связи с датой "OrderData", разве нет?
Таблица Sales, привязанная к таблице 'Date' по связи Sales[Delivery Date] с 'Date'[Date], уже отфильтрована по году - году доставки. Столбец с годом присутствует в таблице Sales, так как она расширенная относительно таблицы 'Date'. Значит таблица Sales, отфильтрованная по году доставки, поступает как внутренний фильтр для меры [Sales Amount], а внешний фильтр по годам на меру [Sales Amount] не действует, так как внутренний фильтр - расширенная таблица Sales со столбцом [Calendar Year] - перебивает внешний.
Дмитрий Никитин написал: внешний фильтр по Brand не действует на меру [Sales Amount] - скрин ?
я перечитал несколько раз, но так и не понял, в чем проблема у Вас? Почему Вы считаете, что внешний фильтр не действует? Вот ваши же меры в разрезе брендов, что в их поведении вызывает смущение?
Потому что внешний фильтр по Product[Brand] фильтрует 2-й аргумент функции CALCULATE:
Код
FILTER(
Sales,
'Sales'[Quantity] > 1
)
А таблица Sales - расширенная относительно таблицы Product, значит включает связанный столбец Product[Brand], поэтому внешний фильтр по Product[Brand] на 1-ый аргумент функции CALCULATE - [Sales Amount] - не действует - скрин
И если это так, тогда я не понимаю, откуда взялся внешний фильтр по годам на 1-ый аргумент функции CALCULATE - [Sales Amount] в мере [Delivered Amount] по связи Sales[OrderDate] с 'Date'[Date] ?
Дмитрий Никитин, у Вас по-моему каша в голове. Все фильтры действуют в мере и внешние (бренд, год) в матрице, и внутренние ('Sales'[Quantity] > 1). В данном случае расчет идет по активной связи календаря (OrderDateKey - DateKey) и в матрице внешний контекст фильтров срабатывает как нужно (Product[Brand] и КалендарьГод. Если еще не понятно, давайте от обратного: вот Вы на скрине пишите , что product[Brand] не фильтрует первую часть выражения. Докажите, какие результаты по Вашему должны получиться? (проверьте в Excel) формулами например.
Цитата
Дмитрий Никитин написал: И если это так, тогда я не понимаю, откуда взялся внешний фильтр по годам на 1-ый аргумент функции CALCULATE - [Sales Amount] в мере [Delivered Amount] по связи Sales[OrderDate] с 'Date'[Date] ?
написал: у Вас по-моему каша в голове. Все фильтры действуют в мере и внешние (бренд, год) в матрице, и внутренние ('Sales'[Quantity] > 1)
Нет у меня никакой каши в голове! Вот привожу вам выдержку из книги "Подробное руководство по DAX":
Цитата
Результатом вызова функции FILTER является ограниченный набор строк из таблицы Sales. А мы помним, что в DAX любое обращение к таблице подразумевает её расширенную версию. Поскольку таблица Sales объединена связью с таблицей Product, её расширенная версия будет также включать все столбцы из таблицы Product. И в числе прочих здесь будет и столбец Product[Brand]
Следовательно, результирующий набор на выходе функции FILTER будет включать значения по всем брендам, соответствующим строкам с количеством проданных товаров, большим единицы.
Но так как в результирующем наборе на выходе функции FILTER также содержится информация о бренде, она будет обладать большим приоритетом... В результате мы... будем видеть итоговое значение по мере Sales Amount для всех транзакций с количеством проданных товаров, превышающих единицу, вне зависимости от выбранного бренда.
Вот на основании этого я и делаю вывод, показанный тут - скрин
Цитата
написал: как откуда? Отсюда
И далее вы приводите другую формулу меры, по которой у меня как раз нет никаких вопросов.
Откуда взялся внешний фильтр по годам на 1-ый аргумент функции CALCULATE - [Sales Amount] в мере [Delivered Amount] по связи Sales[OrderDate] с 'Date'[Date] ?
Дмитрий Никитин написал: В результате мы... будем видеть итоговое значение по мере Sales Amount для всех транзакций с количеством проданных товаров, превышающих единицу, вне зависимости от выбранного бренда.
как это должно выглядеть? В вашей же модели данных все нормально! таблица sales и мера [Multiple Sales] отрабатывают корректно. В матрице сумма разбивается по брендам? Разбивается. Так почему Вы продолжаете писать одно и тоже, что Вы прочитали и таким образом понимаете. Может все же Вы просто что-то неправильно поняли? Еще раз, Вы не привели ни одно факта, что у Вас мера [Multiple Sales] работает некорректно (не учитывает контекст по Product[Brand]), но упорно продолжаете про это писать, потому что Вы так поняли цитату. Напишите страницу, откуда цитата. А то пока....ладно, не буду писать.
Цитата
Дмитрий Никитин написал: Откуда взялся внешний фильтр по годам на 1-ый аргумент функции CALCULATE - [Sales Amount] в мере [Delivered Amount] по связи Sales[OrderDate] с 'Date'[Date] ?
О чем Вы пишите? столбец Sales[OrderDate] не учувствует ни в одной из связей (активная, неактивная), ни в функции USERELATIONSHIP(). По умолчанию связь активная по sales[OrderDataKey] и Calendar[DateKey], отсюда и фильтр и агрегация по годам. В чем проблема я не понимаю. Про поведение Вашей "некорректно" написанной меры [Delivered Amount] я пытался объяснить в сообщение #2. Если не понятно, извините, по другому объяснить не могу. Пишу последний раз: приведите примеры, какой результат Вы ожидаете получить в 1-ом и 2-ом случае работы мер, тогда можно конкретно о чем то говорить. Пока я вижу, что у Вас все-таки каша в голове. А меры отрабатывают ровно так, как и написаны.
написал: мера [Multiple Sales] отрабатывают корректно. В матрице сумма разбивается по брендам? Разбивается. Так почему Вы продолжаете писать одно и тоже, что Вы прочитали и таким образом понимаете. Может все же Вы просто что-то неправильно поняли? Еще раз, Вы не привели ни одно факта, что у Вас мера [Multiple Sales] работает некорректно
Да я и не утверждаю, что мера [Multiple Sales] работает некорректно! Всё нормально с этой мерой. Я только пытаюсь понять, как в точности в этой мере происходит расчёт? Правильно ли я понимаю, что первый аргумент функции CALCULATE фильтруется ТОЛЬКО внутренним фильтром (2-й аргумент функции).
Внешний же фильтр - Product[Brand] отработал на этапе фильтрации 2-го аргумента:
Код
FILTER(
Sales,
'Sales'[Quantity] > 1
)
см. выдержку из книги.
Цитата
написал: Напишите страницу, откуда цитата. А то пока....ладно, не буду писать.
Страницы: 487, 488
Цитата
написал: Пишу последний раз: приведите примеры, какой результат Вы ожидаете получить в 1-ом и 2-ом случае работы мер, тогда можно конкретно о чем то говорить.
а сейчас вижу во втором случае пустые значения и не понимаю, почему так происходит.
А не понимаю я исходя из той логики, которую я описывал на примере меры [Multiple Sales] - внешний фильтр по годам отработал на втором аргументе функции CALCULATE:
Дмитрий Никитин написал: а сейчас вижу во втором случае пустые значения и не понимаю, почему так происходит.
Потому что я уже писал с самого начала про это, вот вижимка:
Цитата
Vladimir Ch написал: Тут возникает одно НО. В функцию CALCULATE() не передан модификатор USERELATIONSHIP(), она только внутри CALCULATETABLE() и соответственно CALCULATE() продолжает считать по текущей активной связи с датой "OrderDataKey". А теперь обратите внимание, что в этих двух столбцах форматы дат абсолютно разные "OrderDataKey" и "Delivery Date". Поэтому CALCULATE() и выдает BLANK(), т.к. форматы дат абсолютно не совпадают.
Теперь на картинках тогда: Чтобы Ваша мера заработала в том виде, котором Вы ее написали, добавьте третью связь с Date по столбцам Sales[OrderDate] и Date[Date] и сделайте активной по умолчанию. Теперь типы данных активной связи и неактивной (DeliveryDate) будут одинаковыми и мера заработает. Я ушел в отпуск, это мое последнее сообщение в данной теме.
написал: Чтобы Ваша мера заработала в том виде, котором Вы ее написали, добавьте третью связь с Date по столбцам Sales[OrderDate] и Date[Date] и сделайте активной по умолчанию. Теперь типы данных активной связи и неактивной (DeliveryDate) будут одинаковыми и мера заработает.
Это я сделал после первого же вашего сообщения Активная связь по умолчанию - скрин1 Неактивная связь - скрин2