В результате всех преобразований получил таблицу, в которой содержатся сведения о всех товарах, входящих в некую товарную накладную (так называемую ПТиУ).
По каждому товару есть сведения о количестве и всех платежах по этому товару: стоимость товара, доставка, хранение и т.д. Далее я строю по таблице сводную, но из-за того, что товары в накладной у меня дублируются по количеству платежей, привязанных к этому товару, дублируется и их количество, и когда я вывожу в строки ПТиУ и товары без наименований платежей, а количество товаров кидаю в значения, то у меня соответственно выдают в разрезе ПТиУ - товар неправильное (задублированное) количество.
Подскажите, пожалуйста, как решить эту проблему?
Сразу скажу, что вытянуть наименования платежа в столбцы - не вариант: их в реальной задаче гораздо больше, к тому же они ещё дополнительно поделены по признаку: облагаются НДС/ не облагаются НДС.
Мне кажется, можно задать какую-то меру, которая бы правильно считала количество в разрезе ПТиУ или ПТиУ-товар, но, к сожалению, я почти забыл DAX за полгода его неиспользования... Помогите, пожалуйста, решить эту проблему.
Получил в работу своеобразную базу с ценами на товары с 2011-го года. Самый быстрый способ её нормализации - через транспонирование с последующим анпивотом. Но у меня есть сомнения в плане лимита по количеству столбцов в Power Query. База будет обновляться, и не получится ли в какой-то момент так, что при транспонировании портянки с ценами превысится максимальный лимит на количество столбцов?
Power.Query. Оптимизация запросов с выгрузкой динамики курсов с сайтов ЦБ РФ, РБ и КЗ, Помощь в оптимизации запросов с выгрузкой динамики курсов валют с сайтов центральных банков с помощью функции Table.Buffer
Помогите, пожалуйста, оптимизировать существующие запросы-подключения к сайтам ЦБ РФ, РБ и КЗ.
Имеется прайс по различным товарам за различные даты. Товары закупаются в России, Беларуси и Казахстане. Цены в прайсе приведены как в российских, так и в белорусских рублях, а также в тенге. Причём цены на товары, закупаемые в Беларуси могут быть указаны как в белорусских рублях, так и в российских. Тоже самое с ценами на товары, закупаемые в Казахстане. Причём сами товары могут закупаться как в национальной валюте, так и в рублях, так и в евро, долларах и юанях. Следовательно, если цены даны в российских рублях, а закупить товары нужно в Белоруссии причём в евро, требуется пересчёт курса евро в российские рубли, но по курсу ЦБ РБ российского рубля по отношению к белорусскому рублю.
Я все необходимые кросс-курсы сделал, к прайсу подтянул. Но ожидаемо всё очень долго подгружается. Я, где смог, добавил Table.Buffer, но не уверен в том, что в плане оптимизации и ускорения сделал всё, что было возможно. Прошу уважаемых знатоков Power Query помочь с оптимизацией.
Валюты тяну с 11-го года, так как статистика ведётся с этого года и для анализа требуются данные за прошлые годы.
DAX. Влияние фильтра по подкатегориям на меру с фильтром по категориям., Не понятна механика фильтрации мер, рассчитанных по категориям, в срезах по подкатегориям
В общем, можете считать меня въедливым занудой, я сформулировал для себя такое правило.
Если внешний фильтр шире гранулярности первого аргумента итерационной функции, то он влияет только на этот аргумент и не влияет на меру во втором аргументе. Если же внешний фильтр Уже гранулярности первого аргумента, то он влияет и на первый аргумент функции и на меру во втором аргументе. А по сути мера во втором аргументе будет рассчитана только в контексте внешнего фильтра в этом случае.
В случае с мерой:
Код
Max Sales Date :=
MAXX(
VALUES('Date'[Date]),
[Sales Amount])
по срезу месяц года действует 1-ое правило. Внешний фильтр - месяц шире гранулярности 1-го аргумента - дня, значит он фильтрует только 1-ый аргумент, а мера вычисляется только в контексте внутреннего фильтра: по каждому дню отфильтрованного месяца.
В случае с мерой:
Код
Max Sales Month :=
MAXX(
VALUES('Date'[Month]),
[Sales Amount])
по срезу дня месяца года (например, 01.01.2007) действует 2-е правило. Внешний фильтр - день Уже гранулярности 1-го аргумента - месяца, значит он фильтрует и первый аргумент: VALUES('Date'[Month]) = "January" и второй аргумент - меру [Sales Amount], но по сути мера рассчитывается только по внешнему фильтру - 01.01.2007
DAX. Влияние фильтра по подкатегориям на меру с фильтром по категориям., Не понятна механика фильтрации мер, рассчитанных по категориям, в срезах по подкатегориям
написал: Однако проблема осталась, тк при присоединении справочника строки дублируются и удаление дублей это полбеды, встает следующая ошибка;у 1 Client ID 2 строчки, где строчка с маркой и строчка с маркой и моделью.а мне по сути надо пришить марку и модель там где есть, а там где нет модели оставить пусто.
Тогда удаляйте дубли по всем столбцам таблицы кроме столбца [Марка и модель]
Только предварительно надо в столбце [Keyword] заменить ошибки на "пусто". Сделать это надо потому, что у вас в этом столбце присутствуют: #ИМЯ? - Power Query такое очень не любит.
DAX. Влияние фильтра по подкатегориям на меру с фильтром по категориям., Не понятна механика фильтрации мер, рассчитанных по категориям, в срезах по подкатегориям
написал: Вы, наверное, не совсем внимательно читали книгу, т.к. там написано (стр. не скажу, доступа к ней в данный момент нет), что при фильтрации по первичному ключу таблицы "Календаря" (в Вашем случае 'Date'[Date]) неявно накладывается модификатор ALL("Календарь").
Ох! )))) Ну уж это я помню, как и то, что вообще любой фильтр в функциях CALCULATE(-TABLE) по какому-либо столбцу автоматически заворачивает условие фильтрации в функцию FILTER:
Код
FILTER(
ALL(Ст-ц),
Ст-ц = (<,>,<>,<=,>=) ....)
А в случае с фильтрацией по 'Date'[Date] ещё и добавляет по умолчанию условие ALL('Date') Только в примерах моих мер функция CALCULATE напрямую вообще не задействована и присутствует лишь как обязательное дополнение к мере [Sales Amount]
Цитата
написал: На уровне месяца января, соответственно 31 дата для вычисления в VALUES('Date'[Date]) и.т.д. Т.е. контексты внутренний и внешний накладываются друг на друга. Где они перебиваются, я не понимаю.
Да вот взять хотя бы пример из видео Руссо. Там мера:
Код
AVERAGEX(
Customer,
[Sales Amount])
рассчитывается в контексте внешнего фильтра - Product[Brand]. Таблицы Product и Customer напрямую не связаны, то есть первый аргумент - таблица Customer внешний контекст фильтра не примет, то есть вернёт всю таблицу Customer целиком. А вот мера [Sales Amount] примет и внешний контекст фильтра - Product[Brand], и внутренний контекст фильтра - каждая строка таблицы Customer. Понятно, что при итерациях по таблице Customer будут пустые строки: 1) либо потому, что данный клиент совсем не совершал покупок; 2) либо потому, что по данному клиенту покупки есть, но с дополнительным внешним фильтром по бренду - их нет. Но функция AVERAGEX игнорит пустые значения, поэтому можно быть уверенным, что расчёт будет верным.
Теперь, что я имею в виду под высказыванием "внутренний фильтр перебивает внешний". И тут заранее прошу меня извинить, если иные мои выводы покажутся вам надругательством над логикой и смысловым извращением.
Возьмём первую меру
Код
Max Sales Date :=
MAXX(
VALUES('Date'[Date]),
[Sales Amount])
в разрезе Года / месяца - например, января 2007-го. Повторю то, что писал выше 1-й аргумент VALUES('Date'[Date]) принимает внешний контекст фильтра - январь 2007-го 2-й аргумент мера [Sales Amount] принимает: 1) внешний контекст фильтра - январь 2007-го; 2) внутренний контекст фильтра - каждый день января 2007-го: с 1-го января по 31-е января И вот тут попробуем наложить внешний контекст фильтра на внутренний Мера [Sales Amount] должна одновременно посчитаться по 1-му января и по всему месяцу январь - вот в точности, как в том примере у Руссо. Но это абсурд, поэтому рассчитывается она только по датам (датам января 2007-го, так как VALUES('Date'[Date]) приняла на себя внешний фильтр по месяцу года). Вот именно это я и имею в виду под "внутренний фильтр перебивает внешний"
Но почему же тогда не абсурд, что во второй мере:
Код
Max Sales Month :=
MAXX(
VALUES('Date'[Month]),
[Sales Amount])
в разрезе даты месяца года - 01.01.2007 мера [Sales Amount] принимает: и внешний фильтр - дата 01.01.2007 и внутренний фильтр - месяц январь (так как внешний фильтр по дате 01.01.2007 отфильтровал первый аргумент VALUES('Date'[Month]) по месяцу "January")
Я вот этого до конца понять не могу. Почему в первой мере нельзя друг на друга наложить внешний и внутренний фильтр, а во второй - можно? Почему, грубо говоря, в первой мере мы не можем посчитать [Sales Amount] одновременно по месяцу и дню, а во второй мере - можем?
DAX. Влияние фильтра по подкатегориям на меру с фильтром по категориям., Не понятна механика фильтрации мер, рассчитанных по категориям, в срезах по подкатегориям
написал: но фильтр по "Bluetooth Headphones" никуда не девается, и по итогу мы получили опять два фильтра "Audio" + "Bluetooth Headphones" = 1.
Огромное вам спасибо!
Я никак до конца не могу уяснить, в каких случаях на меру во втором аргументе итерационной функции действует только внутренний контекст фильтра таблицы в первом аргументе, а в каких ещё и внешний контекст фильтра.
Корни этого непонимания растут вот откуда.
Есть мера, рассчитывающая максимальные продажи в гранулярности дат:
Код
Max Sales Date :=
MAXX(
VALUES('Date'[Date]),
[Sales Amount])
И есть мера, рассчитывающая максимальные продажи в гранулярности месяцев:
Код
Max Sales Month :=
MAXX(
VALUES('Date'[Month]),
[Sales Amount])
Посмотрим, как работает мера "Max Sales Date" в разрезе Года / месяца - например, января 2007-го 1-й аргумент VALUES('Date'[Date]) принимает внешний контекст фильтра - январь 2007-го 2-й аргумент мера [Sales Amount] принимает: 1) внешний контекст фильтра - январь 2007-го; 2) внутренний контекст фильтра - каждый день января 2007-го: с 1-го января по 31-е января Внутренний контекст фильтра перебивает внешний, так как нельзя же одновременно вычислить продажи по месяцу и по дню
Теперь как работает мера "Max Sales Month", но уже в разрезе Года / месяца / дня - например, 1-го января 2007-го года 1-ый аргумент VALUES('Date'[Month]) принимает внешний контекст фильтра - 01.01.2007. Таким образом для 01.01.2007 - VALUES('Date'[Month]) = "January" 2-ой аргумент мера [Sales Amount] принимает: 1) внешний контекст фильтра - 01.01.2007; 2) внутренний контекст фильтра - месяц "January" Тут как раз ситуация аналогична с моим первым примером про категории и подкатегории, то есть оба фильтра - и внешний и внутренний - накладываются на меру - январь и 01.01.2007, то есть мера рассчитывается по 01.01.2007
И вот тут я не до конца понимаю, почему в первом случае внутренний фильтр по датам перебивает внешний по месяцам, а во втором внутренний фильтр по месяцам НЕ перебивает внешний по датам.
Хотя логично всё звучит, но нету точного понимания, когда подобные временные фильтры перебивают один другой, а когда - дополняют друг друга. Если сможете мне это доходчиво объяснить - буду вам признателен!
DAX. Влияние фильтра по подкатегориям на меру с фильтром по категориям., Не понятна механика фильтрации мер, рассчитанных по категориям, в срезах по подкатегориям
DAX. Влияние фильтра по подкатегориям на меру с фильтром по категориям., Не понятна механика фильтрации мер, рассчитанных по категориям, в срезах по подкатегориям
Логика такая: 1) в разрезе категорий - аналогично предыдущей мере; 2) в разрезе подкатегорий - рассуждаю так:
На первый аргумент VALUES('Product'[Category]) влияет фильтр по подкатегории. Подкатегория фильтрует категорию, в которую она входит. Для "Bluetooth Headphones" - это категория "Audio".
На второй аргумент CALCULATE(DISTINCTCOUNT('Product'[Subcategory])) влияет внешний фильтр - подкатегория "Bluetooth Headphones" и внутренний фильтр - категория "Audio". Внутренний фильтр важнее внешнего, значит CALCULATE(DISTINCTCOUNT('Product'[Subcategory])) должен рассчитываться по категории "Audio"
Таким образом по каждой подкатегории: "Bluetooth Headphones", "MP4&MP3" и т.д. значение меры должна быть 3, но выдаёт почему-то 1
написал: то есть в выражении CALCULATE(SUM('Товары'[Прибыль]) есть 3 неявных фильтра по преобразованию контекста, причем из них 2 попадают во внутреннюю итерацию в SUMX : это по [Категория] и [Прибыль] и третий меняется уже в SUMX , а так как у Вас в таблице уникальные пары значений, то получается значение текущей строки. А вот если таблицу немного доработать: для наглядности результат в Таблица3 Товар7 и Товар11.
Да, спасибо!
До меня дошло, наконец, что CALCULATE(SUM('Товары'[Прибыль]) примет ещё и внешний К.Ф., преобразованный из К.С., и помимо фильтра по столбцу "Товар" будет фильтроваться остальными столбцами: "Категория", "Прибыль" и т.д. Таким образом нужно ограничить внешний фильтр столбцом "Товар" и снять с остальных столбцов. Формула:
Код
Накопленная прибыль CALCULATETABLE =
VAR p = 'Товары'[Прибыль]
VAR tab =
CALCULATETABLE(
VALUES('Товары'[Товар]),
ALLEXCEPT('Товары', 'Товары'[Прибыль]),
'Товары'[Прибыль] >= p)
RETURN
SUMX(
tab,
CALCULATE(SUM('Товары'[Прибыль]),
ALLEXCEPT('Товары', 'Товары'[Товар])))
Для последующего ABC-анализа нужно посчитать накопительный итог по товарам. Обычно создавал вычисляемый столбец с помощью функции FILTER:
Код
Накопленная прибыль =
VAR p = 'Товары'[Прибыль]
VAR tab =
FILTER(
'Товары',
'Товары'[Прибыль] >= p)
RETURN
SUMX(
tab,
'Товары'[Прибыль])
Всё корректно считает.
Затем я попробовал ради эксперимента использовать вместо FILTER функцию CALCULATETABLE.
Код
Накопленная прибыль CALCULATETABLE =
VAR p = 'Товары'[Прибыль]
VAR tab =
CALCULATETABLE(
VALUES('Товары'[Товар]),
ALLEXCEPT('Товары', 'Товары'[Прибыль]),
'Товары'[Прибыль] >= p)
RETURN
SUMX(
tab,
CALCULATE(SUM('Товары'[Прибыль])))
Опишу логику формулы.
CALCULATETABLE в отличие от FILTER инициирует преобразование К.С. в К.Ф., следовательно на выражение VALUES('Товары'[Товар]) действуют следующие внешние фильтры: 1. Значение в текущей строке по столбцу "Категория". 2. Значение в текущей строке по столбцу "Прибыль".
Второй и третий аргументы функции CALCULATETABLE задают внутренние фильтры: 1. Фильтровать только по столбцу "Прибыль", игнорить фильтры по остальным столбцам. 2. Весь столбец "Прибыль" (по умолчанию действует доп. условие - ALL( 'Товары'[Прибыль]) ) отфильтровать так, чтобы остались только те значения, что равны или превышают значение в текущей строке столбца "Прибыль".
Внутренний фильтр перебивает внешний, и в итоге остаются только те строки столбца 'Товары'[Товар], что удовлетворяют условиям 2-го и 3-го аргументов функции CALCULATETABLE
Далее в функции SUMX происходит преобразование К.С. в К.Ф. посредством функции CALCULATE, и значение SUM('Товары'[Прибыль]) рассчитывается по каждой строке отфильтрованного столбца VALUES('Товары'[Товар]), а затем все вычисленные значения прибыли суммируются.
По сути логика та же, что и с функцией FILTER, однако формула выдаёт значения не накопительным итогом, а текущей строки столбца "Прибыль".
Для того, чтобы убедиться в справедливости своей логики, я также создал вычисляемый столбец с накопительным итогом по товарам:
Код
Накопленные товары CALCULATETABLE =
VAR p = 'Товары'[Прибыль]
VAR tab =
CALCULATETABLE(
VALUES('Товары'[Товар]),
ALLEXCEPT('Товары', 'Товары'[Прибыль]),
'Товары'[Прибыль] >= p)
RETURN
CONCATENATEX(
tab,
'Товары'[Товар],
", ")
Как и ожидалось, в каждой строке идёт накопление товаров по изложенной выше логике.
Вопрос: почему же не считается накопительный итог?
DAX. Логика табличного фильтра в мере, Хочу понять в точности логику табличного фильтра в мере, заданной с помощью функции CALCULATE и изменённой активной связью с помощью функции USERELATIONSHIP
DAX. Логика табличного фильтра в мере, Хочу понять в точности логику табличного фильтра в мере, заданной с помощью функции CALCULATE и изменённой активной связью с помощью функции USERELATIONSHIP
написал: Чтобы Ваша мера заработала в том виде, котором Вы ее написали, добавьте третью связь с Date по столбцам Sales[OrderDate] и Date[Date] и сделайте активной по умолчанию. Теперь типы данных активной связи и неактивной (DeliveryDate) будут одинаковыми и мера заработает.
Это я сделал после первого же вашего сообщения Активная связь по умолчанию - скрин1 Неактивная связь - скрин2
DAX. Логика табличного фильтра в мере, Хочу понять в точности логику табличного фильтра в мере, заданной с помощью функции CALCULATE и изменённой активной связью с помощью функции USERELATIONSHIP
написал: мера [Multiple Sales] отрабатывают корректно. В матрице сумма разбивается по брендам? Разбивается. Так почему Вы продолжаете писать одно и тоже, что Вы прочитали и таким образом понимаете. Может все же Вы просто что-то неправильно поняли? Еще раз, Вы не привели ни одно факта, что у Вас мера [Multiple Sales] работает некорректно
Да я и не утверждаю, что мера [Multiple Sales] работает некорректно! Всё нормально с этой мерой. Я только пытаюсь понять, как в точности в этой мере происходит расчёт? Правильно ли я понимаю, что первый аргумент функции CALCULATE фильтруется ТОЛЬКО внутренним фильтром (2-й аргумент функции).
Внешний же фильтр - Product[Brand] отработал на этапе фильтрации 2-го аргумента:
Код
FILTER(
Sales,
'Sales'[Quantity] > 1
)
см. выдержку из книги.
Цитата
написал: Напишите страницу, откуда цитата. А то пока....ладно, не буду писать.
Страницы: 487, 488
Цитата
написал: Пишу последний раз: приведите примеры, какой результат Вы ожидаете получить в 1-ом и 2-ом случае работы мер, тогда можно конкретно о чем то говорить.
а сейчас вижу во втором случае пустые значения и не понимаю, почему так происходит.
А не понимаю я исходя из той логики, которую я описывал на примере меры [Multiple Sales] - внешний фильтр по годам отработал на втором аргументе функции CALCULATE:
DAX. Логика табличного фильтра в мере, Хочу понять в точности логику табличного фильтра в мере, заданной с помощью функции CALCULATE и изменённой активной связью с помощью функции USERELATIONSHIP
написал: у Вас по-моему каша в голове. Все фильтры действуют в мере и внешние (бренд, год) в матрице, и внутренние ('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] ?
DAX. Логика табличного фильтра в мере, Хочу понять в точности логику табличного фильтра в мере, заданной с помощью функции CALCULATE и изменённой активной связью с помощью функции USERELATIONSHIP
Потому что внешний фильтр по 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] ?
DAX. Логика табличного фильтра в мере, Хочу понять в точности логику табличного фильтра в мере, заданной с помощью функции CALCULATE и изменённой активной связью с помощью функции USERELATIONSHIP
написал: Тут возникает одно НО. В функцию 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] - перебивает внешний.
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" пустые значения меры объяснены тем, что таблица с привязкой к дате заказа пытается отфильтровать таблицу с привязкой к дате доставки, но откуда вдруг появилась эта таблица с привязкой к дате заказа, когда в формуле задана привязка к дате доставки, я не понимаю.
DAX. Покупки клиентов первого года в разрезе последующих лет, Хочу увидеть продажи тех клиентов, которые совершили покупку в первом отчётном году, в разрезе последующих лет
написал: Для переменной CustomersFirstYear - как раз и нужно ALLSELECTED(), чтоб Ваша мера правильно считала, т.к. в Вашем примере есть фильтр по категориям по строкам, а если покупатель в этом году купил Audio, а в следующем Cell Phone - это покупатель первого года? Вот как раз ALLSELECTED() и убирает это влияние, но при этом, например, во внешнем срезе я вообще не хочу учитывать категорию TV and Videos.
Спасибо! Дошло, наконец, до меня, что FirstYearCustomers в моей последней редакции формулы фильтрует список клиентов не только по 2007-году, но и по конкретной категории товаров, которая приобреталась в 2007-м году. И получается, что формула считает покупки этих клиентов в следующие годы этих же категорий товаров.
Код
VAR FirstYearCustomers =
CALCULATETABLE(
VALUES('Sales'[CustomerKey]),
FirstYear)
VALUES('Sales'[CustomerKey]) принимает внутренний фильтр по первому году (2007 год) и внешний: по категории товаров (внешний фильтр по году перебивает внутренний). В итоге по 2008-му году и, например, категории "Audio" получаем список клиентов 2007-го года, купивших товар из категории "Audio" в 2007-м году
Далее этот список клиентов попадает как условие фильтра в итоговую формулу
Мера [Sales Amount] фильтруется внутренним фильтров по списку клиентов и внешним: по годам и категории товаров. В итоге по 2008-му году и, например, категории "Audio" получаем сумму продаж в 2008-м году по категории "Audio" и по клиентам, покупавшим товары из категории "Audio" в 2007-м.
Наверное, и эта инфа полезна для анализа: объём продаж по той же категории у тех же клиентов в последующие годы, но в данном случае дополнительный фильтр ALL('Product') в переменной VAR FirstYearCustomers решил задачу.
Итоговая формула:
Код
Покупки клиентов 1-го года :=
VAR FirstYear =
CALCULATETABLE(
FIRSTNONBLANK('Date'[Calendar Year Number], [Sales Amount]),
ALL('Date'))
VAR FirstYearCustomers =
CALCULATETABLE(
VALUES('Sales'[CustomerKey]),
FirstYear,
ALL('Product'))
RETURN
CALCULATE(
[Sales Amount],
FirstYearCustomers)
DAX. Покупки клиентов первого года в разрезе последующих лет, Хочу увидеть продажи тех клиентов, которые совершили покупку в первом отчётном году, в разрезе последующих лет
написал: Во-первых, Вы так ничего и не вынесли для себя из прошлой нашей дискуссии по поводу аргументов фильтров функций CALCULATE/CALCULATETABLE, и используете FIRSTNONBLANK('Date'[Calendar Year Number], [Sales Amount]) в качестве аргумента фильтра, который рассчитывает значение в текущем контексте фильтра, а значит для 2007 года - это 2007 год, для 2008 года будет 2008 и т.д.
Да, спасибо. Тут действительно упустил тот момент, что все модификаторы функции CALCULATE действуют только на первый аргумент, а значит на FIRSTNONBLANK('Date'[Calendar Year Number], [Sales Amount]) условие ALL('Date') не распространяется. Я DAX изучаю только полгода, поэтому такие тонкости не всегда замечаю.
Убрал из формулы VALUES('Date'[Calendar Year Number])
Код
Покупки клиентов 1-го года :=
VAR FirstYear =
CALCULATETABLE(
FIRSTNONBLANK('Date'[Calendar Year Number], [Sales Amount]),
ALL('Date'))
VAR FirstYearCustomers =
CALCULATETABLE(
VALUES('Sales'[CustomerKey]),
FirstYear )
RETURN
CALCULATE(
[Sales Amount],
FirstYearCustomers)
но мера считает по-прежнему не верно. Хотя я проверил на табличном выражении
Код
Первый год продаж =
ADDCOLUMNS(
VALUES('Date'[Calendar Year Number]),
"First Year",
CALCULATETABLE(
FIRSTNONBLANK('Date'[Calendar Year Number], [Sales Amount]),
ALL('Date')))
по всем годам календаря выдаёт в качестве первой даты продаж 2007-й год - скрин
Цитата
написал: Во-вторых, если, как Вы утверждаете, что читали ПОДРОБНОЕ РУКОВОДСТВО ПО DAX, Феррари А,ЦитатаА книгу Феррари и Руссо я внимательно читал ( ссылка ) то на странице 422 полностью представлена мера для такого случая:
Да, я читал книгу и пример взял из неё. Логика формулы мне ясна: 1) определяем первый год продаж, 2) фильтруем клиентов по этому году 3) считаем продажи по отфильтрованному списку клиентов.
Однако сама формула мне не понятна: 1) для чего в обеих переменных ALLSELECTED? 2) почему нужна функция KEEPFILTER?
Поэтому я переписал формулу так, как я понимаю, и хочу разобраться, где именно я ошибся. А если просто тупо брать готовые шаблоны из книги без понимания - какой от этого смысл?
DAX. Покупки клиентов первого года в разрезе последующих лет, Хочу увидеть продажи тех клиентов, которые совершили покупку в первом отчётном году, в разрезе последующих лет
DAX. Покупки клиентов первого года в разрезе последующих лет, Хочу увидеть продажи тех клиентов, которые совершили покупку в первом отчётном году, в разрезе последующих лет
Хочу посчитать продажи у тех клиентов, которые совершили покупку в первый год, в разрезе остальных лет.
Вот моя формула меры:
Код
Покупки клиентов 1-го года :=
VAR FirstYear =
CALCULATETABLE(
VALUES('Date'[Calendar Year Number]),
FIRSTNONBLANK('Date'[Calendar Year Number], [Sales Amount]),
ALL('Date'))
VAR FirstYearCustomers =
CALCULATETABLE(
VALUES('Sales'[CustomerKey]),
FirstYear)
RETURN
CALCULATE(
[Sales Amount],
FirstYearCustomers)
Формула выдаёт неправильные результаты. Помогите, пожалуйста, найти ошибку и дополнить формулу. Файл доступен по ссылке - https://disk.yandex.ru/d/kZ3fziTYTRUeVQ