DAX - Как суммировать последние значения по группам? - PullRequest
2 голосов
/ 06 июня 2019

У меня есть 2 таблицы, первая - это очищенная версия данных, вторая - то, что мне нужно вычислить.

AnimalCount
Animal  DATE        Count
Lion    2019-01-01  2
Cat     2019-01-01  45
Cat     2019-01-02  40
Fish    2019-01-02  900
Cat     2019-01-03  50
Fish    2019-01-05  800
Fish    2019-01-06  1200
Cat     2019-01-07  45
Lion    2019-01-07  1
Lion    2019-01-08  0



Calculated
DATE (unique)   Sum of latest Count by Animal
2019-01-01      47 = 45 Cats + 2 Lions
2019-01-02      942 = 900 Fish + 40 Cats + 2 Lions
2019-01-03      952 = 50 Cats + 900 Fish + 2 Lions
2019-01-05      852 = 800 Fish + 50 Cats + 2 Lions
2019-01-06      1252 = 1200 Fish + 50 Cats + 2 Lions
2019-01-07      1246 = 1 Lion + 45 Cats + 1200 Fish
2019-01-08      1245 = 45 Cats + 1200 Fish

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

Буду очень признателен за любые предложения?

Query 1.
LatestTotal = SUMX(
    GROUPBY(
        FILTER(
            AnimalCount,
            [DATE] <= EARLIER([DATE])
        ),
        [Animal],
        "LatestGroupTotal",
        SUMX(CURRENTGROUP(), [Count])
    ),
    [LatestGroupTotal]
)

Query 2.
LatestTotal = SUMX(
    ADDCOLUMNS(
        ADDCOLUMNS(
            VALUES(AnimalCount[Animal]),
            "AnimalName",
            [Animal],
            "LastDate",
            CALCULATE(
                MAX(AnimalCount[DATE]),
                NOT(ISBLANK(AnimalCount[Count]))
            )
        ),
        "LastValue",
        SUMX(
            FILTER(
                AnimalCount,
                [AnimalName] = [Animal]
                && [DATE] = [LastDate]
            ),
            [Count]
        )
    ),
    [LastValue]
)

Ответы [ 2 ]

2 голосов
/ 06 июня 2019

Сначала создайте показатель для общего количества животных (для дальнейшего удобства):

Total Animal Count = SUM(AnimalCount[Count])

Затем добавьте эту меру:

Latest Total = 
VAR 
   Current_Date = MAX ( AnimalCount[DATE] )
VAR 
   All_Latest_Dates =
    ADDCOLUMNS ( 
        ALL ( AnimalCount[Animal] ),
        "Last Date", CALCULATE ( 
                         MAX ( AnimalCount[DATE] ), 
                         AnimalCount[DATE] <= Current_Date )
    )
VAR Animal_Latest_Dates =
    TREATAS ( All_Latest_Dates, AnimalCount[Animal], AnimalCount[DATE] )
RETURN
    CALCULATE ( [Total Animal Count], Animal_Latest_Dates )

Результат:

enter image description here

Пояснение:

Эта формула требует понимания концепции «происхождения данных» в DAX:

Понимание происхождения данных в DAX

Короче говоря:

  • хранить дату, видимую в текущем контексте, в переменной;
  • затем сгенерируйте виртуальную таблицу («All_Latest_Dates»), которая состоит из всех животных и их последней известной даты для каждой «текущей» даты;
  • затем примените эту виртуальную таблицу к таблице AnimalCount, используя TREATAS (пожалуйста, прочитайте статью, чтобы понять, как она работает);
  • наконец, рассчитайте количество животных, используя виртуальную таблицу в качестве нового контекста фильтра.

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

1 голос
/ 06 июня 2019

Как насчет этого?

LatestTotal =
VAR CurrDate =
    MAX ( AnimalCount[DATE] )
VAR Summary =
    SUMMARIZE (
        FILTER ( ALLSELECTED ( AnimalCount ), AnimalCount[DATE] <= CurrDate ),
        AnimalCount[Animal],
        "LastDate", MAX ( AnimalCount[DATE] )
    )
VAR CountAtDate =
    ADDCOLUMNS (
        Summary,
        "Count", LOOKUPVALUE (
            AnimalCount[Count],
            AnimalCount[Animal], [Animal],
            AnimalCount[DATE], [LastDate]
        )
    )
RETURN
    SUMX ( CountAtDate, [Count] )

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

Затем мы смотрим на счет этого животного на эту дату и складываем все эти цифры вместе.

...