Дополнительные вычисления логики операций со временем

Завершено

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

Функции DAX FIRSTDATE и LASTDATE возвращают первую и последнюю дату в текущем контексте фильтра для указанного столбца дат.

Вычисление новых вхождений

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

Первая задача — добавить в таблицу Sales следующую меру, которая подсчитывает количество уникальных клиентов за весь период (LTD). За весь период означает от начальной до конечной даты в контексте фильтра. Отформатируйте меру как целое число, используя разделитель групп разрядов.

Customers LTD =
VAR CustomersLTD =
    CALCULATE(
        DISTINCTCOUNT(Sales[CustomerKey]),
        DATESBETWEEN(
            'Date'[Date],
            BLANK(),
            MAX('Date'[Date])
        ),
        'Sales Order'[Channel] = "Internet"
    )
RETURN
    CustomersLTD

Добавьте меру Customers LTD в матричный визуальный элемент. Обратите внимание, что она создает результат количества уникальных клиентов LTD до конца каждого месяца.

На изображении показан визуальный элемент матрицы с группировкой по годам и месяцам в строках и сводных данных Revenue, Revenue YTD, Revenue YoY % и Customers LTD.

Функция DATESBETWEEN возвращает таблицу, содержащую столбец с датами, начиная с даты начала и заканчивая датой окончания. Если поле даты начала является пустым, функция будет использовать первую дату в столбце даты. И наоборот, если поле конечной даты является пустым, функция будет использовать последнюю дату в столбце даты. В этом случае конечная дата определяется функцией MAX, которая возвращает последнюю дату в контексте фильтра. Таким образом, если август 2017 года находится в контексте фильтра, функция MAX возвратит 31 августа 2017 года, а функция DATESBETWEEN возвратит все даты по 31 августа 2017 года.

Далее вы измените меру, переименовав ее в New Customers и добавив вторую переменную для хранения числа уникальных клиентов до периода времени в контексте фильтра. Предложение RETURN вычитает это значение из числа клиентов LTD, чтобы получить результат, который представляет собой число новых клиентов за этот период времени.

New Customers =
VAR CustomersLTD =
    CALCULATE(
        DISTINCTCOUNT(Sales[CustomerKey]),
        DATESBETWEEN(
            'Date'[Date],
            BLANK(),
            MAX('Date'[Date])
        ),
    'Sales Order'[Channel] = "Internet"
    )
VAR CustomersPrior =
    CALCULATE(
        DISTINCTCOUNT(Sales[CustomerKey]),
        DATESBETWEEN(
            'Date'[Date],
            BLANK(),
            MIN('Date'[Date]) - 1
        ),
        'Sales Order'[Channel] = "Internet"
    )
RETURN
    CustomersLTD - CustomersPrior

На изображении показан визуальный элемент матрицы с группировкой по годам и месяцам в строках и сводных данных Revenue, Revenue YTD, Revenue YoY % и New Customers. Значения New Customers выделяются.

Обратите внимание, что в переменной CustomersPrior функция DATESBETWEEN включает даты до первой даты в контексте фильтра за вычетом единицы. Так как Microsoft Power BI внутренне хранит даты в виде чисел, можно добавлять или вычитать числа, чтобы сместить дату.

Вычисления моментальных снимков

Иногда фактические данные хранятся в виде моментальных снимков до конкретного времени. Распространенные примеры включают в себя уровни запасов в наличии на складе или сальдо по счету. Моментальный снимок значений периодически загружается в таблицу.

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

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

В следующем примере рассматривается сценарий для компании Adventure Works. Переключитесь в представление модели и выберите диаграмму модели Inventory.

На изображении показана диаграмма модели, состоящая из трех таблиц: Product, Date и Inventory. Таблицы Product и Date имеют связь с таблицей Inventory

Обратите внимание, что на диаграмме показаны три таблицы: Product, Date и Inventory. В таблице Inventory хранятся моментальные снимки последнего зафиксированного остатка единиц для каждой даты и продукта. Важно, что в таблице нет отсутствующих дат и нет повторяющихся записей для какого либо продукта в одной и той же дате. Кроме того, последняя запись моментального снимка сохраняется на 15 июня 2020 года.

Теперь переключитесь в представление отчетов и выберите страницу 2. Добавьте столбец UnitsBalance таблицы Inventory в визуальный элемент матрицы. Для формирования сводных данных по умолчанию заданы значения сумм.

На изображении показан визуальный элемент матрицы под заголовком FY2020 Mountain-200 Bike Stock. В нем есть продукты, сгруппированные по строкам, и месяцы, сгруппированные по столбцам. Для каждого продукта и месяца отображаются высокие значения.

Эта конфигурация визуального элемента является примером того, как не суммировать значение моментального снимка. Добавление ежедневных моментальных снимков сальдо не дает осмысленного результата. Таким образом, удалите поле UnitsBalance из визуального элемента матрицы.

Теперь вы добавите в таблицу Inventory меру, которая суммирует значения UnitsBalanceдля одной даты. Это будет последняя дата каждого периода времени. Для этого используется функция LASTDATE. Отформатируйте меру как целое число, используя разделитель групп разрядов.

Stock on Hand =
CALCULATE(
    SUM(Inventory[UnitsBalance]),
    LASTDATE('Date'[Date])
)

Примечание

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

Добавьте меру Stock on Hand в матричный визуальный элемент. Стоимость каждого продукта теперь рассчитывается на основе последнего зафиксированного остатка единиц за каждый месяц.

На изображении показан визуальный элемент матрицы под заголовком FY2020 Mountain-200 Bike Stock. В нем есть продукты, сгруппированные по строкам, и месяцы, сгруппированные по столбцам. Для каждого продукта и месяца отображаются более низкие значения. Июнь 2020 года и поле Total — пустые.

Мера возвращает пустые значения для июня 2020 года, так как для последней даты в июне не существует записей. Эта дата еще не существует.

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

Следующим шагом является настройка формулы меры для определения последней даты с непустым результатом, а затем фильтрация по этой дате. Эту задачу можно выполнить с помощью функции DAX LASTNONBLANK.

Используйте следующее определение меры, чтобы изменить Stock on Hand.

Stock on Hand =
CALCULATE(
    SUM(Inventory[UnitsBalance]),
    LASTNONBLANK(
        'Date'[Date],
        CALCULATE(SUM(Inventory[UnitsBalance]))
    )
)

В визуальном элементе матрицы обратите внимание на значения за июнь 2020 года и итог (за год целиком).

На изображении показано, что визуальный элемент матрицы теперь имеет значения для июня 2020 года и поля Total.

Функция LASTNONBLANK является функцией итератора. Она возвращает последнюю дату, которая выдает непустой результат. Этот результат достигается путем прохода по всем датам в контексте фильтра в хронологическом порядке по убыванию. (И наоборот, FIRSTNONBLANK перебирает даты в хронологическом порядке по возрастанию.) Для каждой даты вычисляется переданное выражение. При обнаружении непустого результата функция возвращает дату. Затем эта дата используется для фильтрации функции CALCULATE.

Примечание

Функция LASTNONBLANK вычисляет свое выражение в контексте строки. Чтобы правильно вычислить выражение, необходимо использовать функцию CALCULATE для переноса контекста строки в контекст фильтра.

Теперь необходимо скрыть столбец UnitsBalance таблицы Inventory. Это предотвратит неправильное суммирование остатка единиц из моментальных снимков от авторов отчетов.