MDX Query, как выбрать первый и последний год периода события
У меня есть datamart от преподавателей моего университета, я хотел бы выбрать список преподавателей с тем, сколько книг они написали и в какой период, когда они публиковали книги.
Пример учителя - последний год публикации - количество книг
Учитель А - 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]
2 ответа
Я наконец нашел способ получить это... Собственно, каждый вычисляемый элемент в предложении "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) Я позволил году присоединиться к предыдущему кортежу с непустым перекрестным соединением ([Anno]. [Anno].Members,);
3) В моем случае DM заказывается еще на год, в другом случае мы должны использовать даже порядок функций;
4) нам не нужны все эти вещи, поэтому мы отбрасываем то, что нам не нужно, используя extract(,[Anno]), это означает, что я буду поддерживать только значения иерархии [Anno];
5) нам просто нужна первая запись упорядоченного списка лет, и мы используем функцию head();
6) мы пока не можем использовать это значение, иначе MDX будет считать записи в таблице фактов для значения [Anno], которое мы выбрали, поэтому мы преобразуем его как строку с помощью setToStr ();
7) значение все еще грязное, потому что строка также имеет hiearchy, поэтому мы очищаем ее, используя функции left() и right() (год всегда состоит из 4 символов).
Это немного большая функция, но это единственное, что сработало для меня:)
Мерам требуется некоторая форма значения или строки для возврата, я думаю, именно поэтому ваша мера возвращает 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];