Проверьте, является ли уровень в любой иерархии измерений [Foo] - PullRequest
0 голосов
/ 05 июля 2011

В моем измерении даты у меня есть 2 иерархии:

[Год - неделя - Дата] и [Год - Месяц - Дата]

Я хочу проверить в вычислении куба, является ли текущий уровень измерения даты [Дата] (самый низкий уровень) или что-то более высокое.

Как мне этого добиться?

Справочная информация: Мне нужно это, чтобы рассчитать, сколько рабочих дней было в периоде для сотрудника.В настоящее время у меня есть этот код (непроверенный), который должен выполнить трюк для 1 иерархии, но я предполагаю, что это не удастся, если пользователи используют иерархию [Год - Неделя - Дата].

CASE WHEN
    [Date].[Year - Month - Date].CURRENTMEMBER.Level
IS
    [Date].[Year - Month - Date].[Date]
THEN
    //at day level,

    //if there is any duration booked, this is a working day
    IIF([Measures].[Duration] = 0,0,1)

ELSE
    //at higher than day level,

    //count days
    COUNT(
        // where duration > 0 (employee work day)
        FILTER(
            Descendants([Date].[Year - Month - Date].CURRENTMEMBER, [Date].[Year - Month - Date].[Date]),
            [Measures].[Duration] > 0
        )
    )

END

tl; dr как сделать так, чтобы вышеуказанный код также работал для иерархии [Год - Неделя - Дата] самым чистым способом.

Ответы [ 4 ]

2 голосов
/ 05 июля 2011

Давайте предположим, что иерархия (он же атрибут) [Дата]. [Дата] существует. Если это так, вы можете упростить:

  COUNT(
    FILTER( Existing [Date].[Date].members, [Measures].[Duration] > 0 )
  )

Существующий заставит автоматически применить существование к измерению [Дата]. Это в основном улучшение производительности, так как не нужно оценивать (фактически) все кортежи.

Как только предыдущие примеры понятны, мы можем объединить их с вашей версией для быстрого решения (нет необходимости в первом iif):

  COUNT(
    FILTER( Existing 
       Descendants([Date].[Year - Month - Date].CURRENTMEMBER, [Date].[Year - Month - Date].[Date],self) 
       , [Measures].[Duration] > 0 )
  )

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

1 голос
/ 07 августа 2011

IsLeaf() сообщит вам, находится ли участник на нижнем уровне.

1 голос
/ 06 июля 2011

Если вы ищете самый простой способ подсчитать, сколько рабочих дней было за период, вы должны подражать поведению регулярных измерений. В противном случае вы получите ошибку или неверные данные в случае множественного выбора [Дата]. Кроме того, желательно оставить выражение Count (Filter (...)), чтобы сохранить режим вычисления блока (см. Оптимизация выражений Count (Filter (...)) в MDX ). Для этого выполните следующие действия:

  1. Перейти к представлению источника данных.
  2. Создайте новый именованный расчет рядом со столбцом [Продолжительность] (в той же таблице фактов).
  3. Имя столбца «Рабочие дни», выражение «ноль».
  4. Создать новую регулярную меру на основе столбца «Рабочие дни». Функция агрегирования - Sum.
  5. Запись в сценарии MDX:

    (
        [Date].[Date].[Date].Members,
        [Measures].[Working days]
    ) = Iif( [Measures].[Duration] > 0, 1, null );
    
0 голосов
/ 05 июля 2011

Посмотрите на команды SCOPE в вашем скрипте вычислений, я делаю нечто подобное для моего календаря YMD и моего календаря YWD:

CREATE MEMBER CurrentCube.Measures.Example AS NULL //Dummy will be calc'd later

SCOPE (DESCENDANTS([Date].[Calender Y M D],,AFTER));    
 Measures.Example = 1; //Fill in for monthly calcs
END SCOPE

SCOPE (DESCENDANTS([Date].[Calender Y W D],,AFTER));    
 Measures.Example = 2; //Fill in for weekly calcs
END SCOPE

Синтаксис с, ,, AFTER, состоит в исключении члена All, если я правильно помню, я пытаюсь изменить ссылку, но не могу найти ее. В качестве альтернативы, если расчет хорошо работает с элементом ALL, просто используйте SCOPE([Date].[Calender Y W D])

...