Рассчитать родительское значение на уровне листа из таблицы фактов с различными уровнями гранулярности - PullRequest
0 голосов
/ 26 февраля 2019

Я не уверен, подходит ли модель данных для того, что я хочу вычислить, но я хотел бы сначала попробовать, если это возможно, согласно предоставленному формату набора данных.

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

enter image description here

Содержит население на уровне страны, а также по регионам или группам экономики в соответствии с действующей классификацией Всемирного банка (файл Excel на веб-сайте Всемирного банка).

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

Для примера это выглядит следующим образом: некоторые страны и регионы экономики выбраны и должны быть рассчитаны вместе.

enter image description here

Мне нужно рассчитать с помощью DAX (Power Pivot / SSAS 2017 или Power BI) коэффициент популяции ребенка по сравнению сродительский уровень, также, если сводная таблица содержит только конечные элементы .

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

Я строю иерархию в соответствии с решением от Альберто Феррари.

enter image description here

Population wrong:=
IF (
    [BrowseDepth] > [MaxNodeDepth];
    BLANK ();
    SUM ( population[Value] )
)

Чтобы не вычислять ребенкаУровень на родительском уровне, я использую эти меры:

Population w/o aggregation:=
IF (
    [BrowseDepth] = [MinNodeDepth];
    CALCULATE (
        SUM ( population[Value] );
        FILTER (
            population;
            population[Country Code] = CALCULATE (
                VALUES ('country'[Country code]);
                FILTER (
                    'country';
                    'country'[HierarchyDepth] = MIN ('country'[HierarchyDepth])
                )
            )
        )
    )
)


RatioToParent:=
IF (
    ISFILTERED ( country[Level2] )
        && NOT ( ISFILTERED ( country[Level3] ) );
    [Population w/o aggregation]
        / CALCULATE ( [Population w/o aggregation]; ALL ( country[Level2] ) );
    IF (
        ISFILTERED ( country[Level3] ) && NOT ( ISFILTERED ( country[Level4] ) );
        [Population w/o aggregation]
            / CALCULATE ( [Population w/o aggregation]; ALL ( country[Level3] ) );
        IF (
            ISFILTERED ( country[Level4] );
            [Population w/o aggregation]
                / CALCULATE ( [Population w/o aggregation]; ALL ( country[Level4] ) )
        )
    )
)

Пока я использую иерархию в строках сводной таблицы, я могу вычислить соотношение как требуется:
enter image description here

Например, страны со средним уровнем дохода составляют 75% мирового населения (в 2010 году), более низкий средний доход составляет 53% этой группы.

Однакоесли я просто возьму поле страны, а не иерархию, то вышеупомянутая мера не вычисляет какое-либо значение (вероятно, из-за мер [BrowseDepht] и [NodeDepth]).

Я не могу найти способкак вывести на детский уровень население ваlue родителя, так как значение не является суммой всех дочерних элементов.Без этого значения отношение не может быть вычислено.

Любая подсказка была бы очень признательна.

enter image description here

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

1 Ответ

0 голосов
/ 27 февраля 2019

Я нашел частичное решение для замены этой начальной меры:

RatioToParent:=IF (
    ISFILTERED ( country[Level2] )
        && NOT ( ISFILTERED ( country[Level3] ) );
    [Population w/o aggregation]
        / CALCULATE ( [Population w/o aggregation]; ALL ( country[Level2] ) );
    IF (
        ISFILTERED ( country[Level3] ) && NOT ( ISFILTERED ( country[Level4] ) );
        [Population w/o aggregation]
            / CALCULATE ( [Population w/o aggregation]; ALL ( country[Level3] ) );
        IF (
            ISFILTERED ( country[Level4] );
            [Population w/o aggregation]
                / CALCULATE ( [Population w/o aggregation]; ALL ( country[Level4] ) )
        )
    )
)

Без использования функции ISFILTERED я получил эту меру:

RatioToParent 2:=IF (
    HASONEVALUE ( country[Country code] );
    DIVIDE (
        SUM ( population[Value] );
        IF (
            VALUES ( country[Level] ) = 1;
            BLANK ();
            IF (
                VALUES ( country[Level] ) = 2;
                CALCULATE (
                    SUM ( population[Value] );
                    VALUES ( country[Level1] );
                    FILTER ( ALL ( country ); country[Level] = 1 )
                );
                IF (
                    VALUES ( country[Level] ) = 3;
                    CALCULATE (
                        SUM ( population[Value] );
                        VALUES ( country[Level2] );
                        FILTER ( ALL ( country ); country[Level] = 2 )
                    );
                    IF (
                        VALUES ( country[Level] ) = 4;
                        CALCULATE (
                            SUM ( population[Value] );
                            VALUES ( country[Level3] );
                            FILTER ( ALL ( country ); country[Level] = 3 )
                        )
                    )
                )
            )
        )
    )
)

enter image description here

Однако эта мера еще не переносима.Если поместить в исходную иерархию, уровни с потомками не будут рассчитываться (из-за функции HASONEVALUE, которая необходима для предотвращения ошибки DAX).enter image description here

Может быть, кто-нибудь знает, как сделать последнюю меру "RatioToParent 2" переносимой, без функции HASONEVALUE.

...