Запрос MDX, как выбрать первый и последний год периода события

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

Пример Учитель - Последний год публикации - Количество книг

Учитель А - 2014 - 200 книг

Я попытался сделать что-то вроде:

WITH MEMBER [Measures].[LastYear] AS 
   '(ClosingPeriod([Anno].[Anno])
         ,[Autore].[Nome].CurrentMember)'
SELECT 
  {[Measures].[Unita (Libri)],[Measures].[LastYear]} ON COLUMNS,
NON EMPTY 
   [Autore].[Nome].Members ON ROWS
FROM [Pubblicazioni]

но поле в прошлом году всегда пустое, если я попытаюсь изменить вторую часть ClosingPeriod с помощью [Measures].[Unita (libri)], оно тоже будет пустым... Как мне реализовать этот запрос? я немного запутался

РЕДАКТИРОВАТЬ

select [Measures].[Libri] ON COLUMNS,
crossjoin([Autore.default].[Nome].[Fazzinga, Bettina], tail(NonEmptyCrossJoin([Autore.default].[Nome].[Fazzinga, Bettina], [Anno.default].[Anno].Members), 1).Item(0).Item(1)) ON ROWS
from [Pubblicazioni]

Это отлично работает для учителя [Фаззинга, Беттина], но запрос перестает работать, пока я делаю

select [Measures].[Libri] ON COLUMNS,
crossjoin([Autore.default].[Nome].Members, tail(NonEmptyCrossJoin([Autore.default].[Nome].CurrentMember, [Anno.default].[Anno].Members), 1).Item(0).Item(1)) ON ROWS
from [Pubblicazioni]

person Neo87    schedule 05.11.2014    source источник
comment
Как насчет использования агрегации MAX() для нахождения максимального года (то есть самого последнего года для этого учителя) вместо агрегации SUM()?   -  person Magnus Smith    schedule 05.11.2014
comment
Я пытался использовать что-то вроде WITH MEMBER [Measures].[TopYear] AS 'max([Anno].[Anno].Members)', и это дает мне такие значения, как 3, 4, 5... Я не знаю, почему   -  person Neo87    schedule 05.11.2014
comment
Вы можете прочитать о функции AGGREGATE(), которая немного отличается от того, что вы там делали. См. msdn.microsoft.com/en-us/library/ms145524.aspx   -  person Magnus Smith    schedule 06.11.2014
comment
@MagnusSmith, что мне делать с агрегатом? о.о   -  person Neo87    schedule 06.11.2014
comment
Я думал, что список всех лет, когда учитель опубликовал книгу, можно превратить в «последнюю дату публикации», ища максимум. Извините, что ввел вас в заблуждение с помощью AGGREGATE(), я вижу, что это будет полезно, только если для самого куба параметр агрегирования установлен на MAX (по умолчанию SUM).   -  person Magnus Smith    schedule 07.11.2014
comment
@MagnusSmith, кажется, я понимаю, о чем ты сейчас говоришь. Я должен установить новую меру в кубе с агрегацией max() и Column Year :)   -  person Neo87    schedule 12.11.2014


Ответы (2)


Мерам требуется какая-то форма значения или строки для возврата, я думаю, именно поэтому ваша мера возвращает void, поскольку ClosingPeriod возвращает член, а не значение.

Следующее не тестируется:

WITH MEMBER [Measures].[LastYear] AS 
   '(Tail(
       nonempty(
         [Anno].[Anno]
         ,([Autore].[Nome].CurrentMember, [Measures].[Unita (Libri)])
       )
    ).item(0).item(0).MEMBERVALUE)'
SELECT 
  {[Measures].[Unita (Libri)],[Measures].[LastYear]} ON COLUMNS,
NON EMPTY 
   [Autore].[Nome].Members ON ROWS
FROM [Pubblicazioni]

Вместо этого попробуйте это:

SELECT 
  [Measures].[Libri] ON COLUMNS

 ,Generate
  (
    [Autore.default].[Nome].MEMBERS
   ,Tail
    (
      //NonEmptyCrossJoin <<hopefully nonempty is enough
      NonEmpty
      (
        [Autore.default].[Nome].CurrentMember * [Anno.default].[Anno].MEMBERS
      )
     ,1
    ) //.Item(0).Item(1) //<<don't believe this is required
  ) ON ROWS
FROM [Pubblicazioni];
person whytheq    schedule 05.11.2014
comment
Ошибка Мондриана: ни одна функция не соответствует сигнатуре «непустой (‹Level›, ‹Tuple›)», так или иначе, я отредактировал вопрос с новым запросом (подумал об этом, просмотрев ваш запрос), но .currentmember не работает :(. И если я использую результат как [Measures].[LastYear] в COLUMNS дает мне количество книг - person Neo87; 06.11.2014

Наконец-то я нашел способ получить его... Изначально каждый вычисляемый элемент в предложении "WITH MEMBER" обрабатывается как информация о кубе. В моем случае, если я сделаю max("выражение лет, когда автор работал"), это даст количество книг, которые он написал в относительном максимальном году. Чтобы этого избежать, существует конструкция SetToStr(), которая печатает год в виде строки (что-то вроде [Hyerarchie].[Level].[Value]). Строка может быть просто вырезана с помощью условий left() и right(). Вот результат:

WITH MEMBER [Measures].[Anno prima pubblicazione] AS 'left(right(settostr(head(extract(nonemptycrossjoin([Anno].[Anno].Members, nonemptycrossjoin([Libro].[Titolo].Members,[Autore].[Nome].CurrentMember)),[Anno]),1)),6),4)'
MEMBER [Measures].[Anno ultima pubblicazione] AS 'left(right(settostr(tail(extract(nonemptycrossjoin([Anno].[Anno].Members, nonemptycrossjoin([Libro].[Titolo].Members,[Autore].[Nome].CurrentMember)),[Anno]),1)),6),4)'
SELECT {[Measures].[Anno prima pubblicazione],[Measures].[Anno ultima pubblicazione]} ON COLUMNS,
[Autore].[Nome].Members ON ROWS
FROM [Pubblicazioni]

Этот запрос работает следующим образом:

1) извлечь книги для текущего автора с помощью nonemptycrossjoin([Libro].[Titolo].Members,[Autore].[Nome].CurrentMember), чтобы я получил кортеж;

2) я позволяю году присоединиться к предыдущему кортежу с помощью nonemptycrossjoin([Anno].[Anno].Members,);

3) В моем случае DM заказан еще на год, в противном случае мы должны использовать даже функцию order;

4) нам все это не нужно, поэтому мы выбрасываем то, что нам не нужно, используя extract(,[Anno]), это означает, что я буду поддерживать только значения иерархии [Anno];

5) нам просто нужна первая запись упорядоченного списка лет, и мы используем функцию head();

6) мы пока не можем использовать это значение, иначе MDX подсчитает записи в таблице фактов для выбранного нами значения [Anno], поэтому мы преобразуем его в строку с помощью setToStr();

7) значение по-прежнему грязное, потому что строка тоже имеет иерархию, поэтому мы очищаем ее с помощью функций left() и right() (год всегда состоит из 4 символов).

Это немного большая функция, но это единственная, которая работала для меня :)

person Neo87    schedule 13.11.2014