Что именно возвращает функция Allexcept () в развернутых таблицах? И почему? - PullRequest
1 голос
/ 21 мая 2019

Функция Allexcept описана практически одинаково в «Определенном руководстве по DAX»:

«Вы также можете указать одну целую таблицу вместо всех столбцов таблицы, являющейся частью расширенной таблицы»(P430)

и dax.guide:

"ALLEXCEPT удаляет фильтры из расширенной версии Sales, которая включает в себя все таблицы, к которым можно получить доступ, начиная с отношения" многие к одному "от продаж. "https://www.sqlbi.com/articles/managing-all-functions-in-dax-all-allselected-allnoblankrow-allexcept/

И все они подразумевают, что Allexcept возвращает таблицу, когда она не используется как верхняя функция в Calculate в качестве аргументов фильтра, точно так же, как это делает All (), хотя в моей практике это нечто иное:

Рассмотрим модель с одной таблицей, например:

Name    Datetime
John    2018/6/25
James   2018/7/7
Smith   2018/7/27
Smith   2018/11/21
Smith   2018/6/9
Mary    2019/1/31
Emily   2018/8/20
John    2018/6/9
Mary    2018/11/11
John    2018/8/21

со связанным календарем, используя Calendarauto () с вычисляемым столбцом:

YearMonth = FORMAT('Date'[Date],"yyyymm")

Теперь я хочу узнать, сколькоYearMonth соответствует каждому Имени, которое должно быть таким:

Name MonthNum
John    2
James   1
Smith   3
Mary    2
Emily   1

Зная расширенные таблицы и Allexcept (и как работает контекстный переход), я использовал следующую формулу:

Wrong = 
ADDCOLUMNS (
    VALUES ( Data[Name] ),
    "MonthNum", CALCULATE (
            DISTINCTCOUNT ( 'Date'[YearMonth] ),
            CALCULATETABLE ( ALLEXCEPT ( Data, Data[Name] ) )
        )
    )

Результат оказывается:

Name    MonthNum
John    5
James   5
Smith   5
Mary    5
Emily   5

Но я ДЕЛАЮ ЗНАЮ, как сделать все правильно, добавив «Данные» после Calculatetable:

  Correct = 
ADDCOLUMNS (
    VALUES ( Data[Name] ),
    "MonthNum", CALCULATE (
            DISTINCTCOUNT ( 'Date'[YearMonth] ),
            CALCULATETABLE ( Data, ALLEXCEPT ( Data, Data[Name] ) )
        )
    )

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

Ответы [ 2 ]

1 голос
/ 23 мая 2019

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

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

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

Теперь давайте посмотрим, почему работает корректно один, но другой отказывает в вашем случае.Давайте сначала выделим таблицы вычислений.

Правильная - correct_calc = CALCULATETABLE ( Sheet1, ALLEXCEPT ( Sheet1, Sheet1[Name] ) )

возвращает

correct calculate table

при неправильномone - wrong_calc = CALCULATETABLE ( ALLEXCEPT ( Sheet1, Sheet1[Name] ) )

возвращает

wrong calculated table

С учетом этих таблиц, я бы предположил, что правильное имя сохраняет "имя«Фильтры, поскольку они существуют в вычисляемой таблице, поэтому движок видит для каждого« имени »только часть таблицы.

Неправильный, с другой стороны, просто сохраняет все даты, независимо от фильтра «имен», так как значения «имен» вообще не учитываются, поскольку между VALUES ( Data[Name] ) нет никакой связии таблица, по которой вы производите вычисления, например, CALCULATETABLE ( ALLEXCEPT ( Data, Data[Name] ) ).

При написании ответа я понял, что это не точная причина, как вы просили, поэтому мои извинения.

0 голосов
/ 24 мая 2019

Я провел много тестов, чтобы выяснить, как именно ведет себя Allexcept (), и вот мой вывод:

Allexcept () имеет 2 различных поведения, как и All ():

1. как «removefilter», таким образом он удаляет все фильтры из столбцов, которые не исключены из расширенной таблицы, но сам по себе ничего не возвращает;

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

Поведение 1 слишком ясно, чтобы его можно было объяснить. Чтобы активировать это поведение, просто используйте allexcept () как верхнюю функцию в Calculate () или Calculatetble () в качестве аргумента фильтра.

Поведение 2 гораздо сложнее доказать и понять.

Эта формула доказывает, что Allexcept () может возвращать таблицу и таблица результатов является неполной (настоятельно рекомендуется использовать DAXStudio для проверки результата):

EVALUATE
GENERATE (
    VALUES ( Data[Name] ),
    CALCULATETABLE ( ALLEXCEPT ( Data, Data[Name] ) )
)

Это показывает, что Allexcept () может возвращать таблицу самостоятельно, когда это необходимо:

EVALUATE
GENERATE ( VALUES ( Data[Name] ), ALLEXCEPT ( Data, Data[Name] ) )

Это показывает, что таблица результатов, возвращаемая Allexcept (), является расширенной:

EVALUATE
CALCULATETABLE ( 'Date', CALCULATETABLE ( ALLEXCEPT ( Data, Data[Name],Data[Datetime],Data[Type] ) ) ) 

И последняя формула показывает, что при использовании в качестве возвращателя таблицы Allexcept () игнорирует любой аргумент фильтра в исходной расширенной таблице, включая как исключенные столбцы, так и не исключенные, что означает, что все фильтры в исходном расширенном столбце столы бесполезны:

CALCULATETABLE (
    'Date',
    CALCULATETABLE (
        ALLEXCEPT ( Data, Data[Name] ),
        Data[Name] = "Tom",
        'Date'[YearMonth] ="2018-1-1"
    )
)

Пожалуйста, прокомментируйте, если у вас есть какие-либо советы!

...