powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / OLAP и DWH [игнор отключен] [закрыт для гостей] / Логика расчета
32 сообщений из 32, показаны все 2 страниц
Логика расчета
    #39413585
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте!

Есть 4 варианта вычисляемых мер в MDX-запросе.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
WITH
SET [Анализируемый месяц] AS [Время].[Месяц].&[2016-12-01T00:00:00] 

MEMBER [Measures].[Вычисляемая мера Вариант1] AS	
	    SUM([Анализируемый месяц],
	    	    [Measures].[Мера1]) * 
	    SUM([Анализируемый месяц].Item(0).Lag(1),
		    [Measures].[Мера2] / [Measures].[Мера1])	

MEMBER [Measures].[Вычисляемая мера Вариант2] AS	
	    SUM([Анализируемый месяц],
	 	    [Measures].[Мера1]) * 
	    SUM([Анализируемый месяц].Item(0).Lag(1),
		    [Measures].[Мера2]) /
	    SUM([Анализируемый месяц].Item(0).Lag(1),
		    [Measures].[Мера1])

MEMBER [Measures].[Вычисляемая мера Вариант3] AS
	(CASE WHEN SUM([Анализируемый месяц].Item(0).Lag(1),[Measures].[Мера1])<>0  THEN
	    SUM([Анализируемый месяц],
	    	    [Measures].[Мера1]) * 
	    SUM([Анализируемый месяц].Item(0).Lag(1),
		    [Measures].[Мера2] / [Measures].[Мера1])
	END)

MEMBER [Measures].[Вычисляемая мера Вариант4] AS
	(CASE WHEN SUM([Анализируемый месяц].Item(0).Lag(1),[Measures].[Мера1])<>0  THEN
	    SUM([Анализируемый месяц],
	 	    [Measures].[Мера1]) * 
	    SUM([Анализируемый месяц].Item(0).Lag(1),
		    [Measures].[Мера2]) /
	    SUM([Анализируемый месяц].Item(0).Lag(1),
		    [Measures].[Мера1])
       END)

SELECT
	{[Measures].[Вычисляемая мера Вариант1],
	[Measures].[Вычисляемая мера Вариант2],
	[Measures].[Вычисляемая мера Вариант3],
	[Measures].[Вычисляемая мера Вариант4]} ON 0,
NON EMPTY
	[SKU].[SKU].[SKU] ON 1
FROM
	(SELECT [Время].[Месяц].&[2016-11-01T00:00:00]: [Время].[Месяц].&[2016-12-01T00:00:00] on 0 FROM Profit)


Выдает такой результат:
SKUВычисляемая мера Вариант1Вычисляемая мера Вариант2Вычисляемая мера Вариант3Вычисляемая мера Вариант4SKU1500.22500.22457889500.22457889500.22457889SKU2600.94600.9441800486600.9441800486600.9441800486

1. Корректно считать, что следующие записи из варианта 1 и 2 равносильны?
Код: sql
1.
2.
3.
SUM([Анализируемый месяц].Item(0).Lag(1), [Measures].[Мера2] / [Measures].[Мера1])	
и
SUM([Анализируемый месяц].Item(0).Lag(1), [Measures].[Мера2]) / SUM([Анализируемый месяц].Item(0).Lag(1),  [Measures].[Мера1])

И почему в первом варианте в результате короткая дробная часть?


2. Обратите внимание в 3 и 4 варианте, когда добавили проверочное условие,то в результате присутствуют только длинные дробные части. Не как вариант 1 и 2. Почему так?


3. Если запись в субкубе
Код: sql
1.
[Время].[Месяц].&[2016-11-01T00:00:00]:[Время].[Месяц].&[2016-12-01T00:00:00]

заменить на
Код: sql
1.
[Время].[Месяц].&[2016-12-01T00:00:00]

, то результат тот же самый. Если в субкубе я задал декабрь 2016, то MDX в кубе все равно вытягивает предыдущий месяц и не показывает ошибку. Почему так?
...
Рейтинг: 0 / 0
Логика расчета
    #39413625
ShIgor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ferzmikk,

1 - да конечно! потому что у Вас сумма конкретной координаты, а не набора.

2 - почему короткая - не знаю, sql при перемножении/делении тоже увеличивает размерности numeric, например (5,2) станет (10,4)

3 - разжевывали много раз - подселект не влияет на контекст вычислений, это можно даже заметить, что вычисляемый член [Анализируемый месяц] не входит в подселект, это не alias [Время].[Месяц].&[2016-12-01T00:00:00] - это вычисляемый член, поэтому все-равно что Вы поставите в подселекте.
...
Рейтинг: 0 / 0
Логика расчета
    #39413698
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ShIgor,

Спасибо!
...
Рейтинг: 0 / 0
Логика расчета
    #39414507
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Усложнятся задача.

MDX-запрос по каждой SKU выгружает вычисляемую меру. Суть в том, что если выгружаемый месяц является текущим или предыдущим, то расчет по формуле, если месяц позапрошлый или ранее то просто выгружается мера без расчетов. Пытаюсь сообразить как это сделать.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
WITH
SET [Текущий месяц] AS
	StrToMember("[Время].[Месяц].&[" + VBA!Format(VBA!Dateadd('m', 0, VBA!Now()), 'yyyy-MM-01T00:00:00') + "]")
SET [Анализируемый месяц] AS 
	[Время].[Месяц].&[2017-02-01T00:00:00] 

MEMBER [Measures].[Вычисляемая мера] AS
	//Если Анализируемый месяц является текущим или прошлым
	(CASE WHEN ...
		(CASE WHEN SUM([Анализируемый месяц].Item(0).Lag(2),[Measures].[Мера1])<>0  THEN
			SUM([Анализируемый месяц],
				[Measures].[Мера1]) * 
			SUM([Анализируемый месяц].Item(0).Lag(2),
				[Measures].[Мера2]  /	[Мера1])
		END)
	//Если анализируемый месяц является позапрошлым или ранее
	WHEN ...
		SUM([Анализируемый месяц].Item(0).Lag(2), [Measures].[Мера2])
	//Учет риска. Вдруг будет выбран будущий период
	ELSE
		
	END)
SELECT
	([Measures].[Вычисляемая мера],   [Анализируемый месяц]) ON 0,
NON EMPTY
	[SKU].[SKU].[SKU]
ON 1
FROM
	(SELECT	[Время].[Месяц].&[2016-12-01T00:00:00]:[Время].[Месяц].&[2017-02-01T00:00:00] on 0 FROM Profit)


Нужно условие как то правильно написать, типа
Код: sql
1.
[Текущий месяц].CurrrentMember = [Анализируемый месяц].CurrrentMember 

Хотя по логике CurrentSet нужен, но не существует в MDX.

Как правильно написать?
...
Рейтинг: 0 / 0
Логика расчета
    #39414620
ShIgor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ferzmikk,

Не вникая в задачу...
во всех расчетах везде указан конкретный член, поэтому не понимаю 2х вещей, зачем объявлять сеты из одного члена, причем не рекомендованным способом и зачем использовать функцию SUM? (сумма значений массива из одного элемента равна значению этого элемента)
...
Рейтинг: 0 / 0
Логика расчета
    #39414639
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ShIgorferzmikk,

Не вникая в задачу...
во всех расчетах везде указан конкретный член, поэтому не понимаю 2х вещей, зачем объявлять сеты из одного члена, причем не рекомендованным способом
Потому что это простой пример запроса для понимания сути задачи. На самом деле вычисляемых мер больше и затрагивают другие месяцы. В один сет заталкиваю один месяц как переменную, потом во второй сет как вторую переменную, и т. д., чтобы каждый раз не менять месяцы в других строках MDX-запроса. Получаем несколько мер по разным месяцам.
и зачем использовать функцию SUM? (сумма значений массива из одного элемента равна значению этого элемента)
Вообще задается период, так как нужны разные месяцы. Возможно что то не учитываю. Если так, то пожалуйста, поправьте.
...
Рейтинг: 0 / 0
Логика расчета
    #39414686
ShIgor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ferzmikkВ один сет заталкиваю один месяц как переменную, потом во второй сет как вторую переменную
почему сет, а не мембер?
ferzmikkВообще задается период, так как нужны разные месяцы. Возможно что то не учитываю.
не вижу периода, а в подселекте выяснили уже - не влияет
...
Рейтинг: 0 / 0
Логика расчета
    #39414951
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ShIgorferzmikkВ один сет заталкиваю один месяц как переменную, потом во второй сет как вторую переменную
почему сет, а не мембер?
Вот такой MDX-запрос.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
WITH
SET [МесяцТекущий] AS [Время].[Месяц].&[2017-02-01T00:00:00]
SET [Месяц1] AS [Время].[Месяц].&[2017-01-01T00:00:00]
SET [Месяц2] AS [Время].[Месяц].&[2016-12-01T00:00:00]
SET [Месяц3] AS [Время].[Месяц].&[2016-11-01T00:00:00]
SET [МесяцПрошлогоГода] AS [Время].[Месяц].&[2016-02-01T00:00:00]

//Мера1
//Специально не используя функцию AVG, так как пустые значения игнорирует, а нули - нет.
MEMBER [Мера1 Месяц1] as sum([Месяц1], [Measures].[Мера1])
MEMBER [Мера1 Месяц2] as sum([Месяц2], [Measures].[Мера1])
MEMBER [Мера1 Месяц3] as sum([Месяц3], [Measures].[Мера1])
MEMBER [Есть Мера1 Месяц1] AS (CASE WHEN [Мера1 Месяц1] > 0 THEN 1  ELSE 0 END)
MEMBER [Есть Мера1 Месяц2] AS (CASE WHEN [Мера1 Месяц2] > 0 THEN 1  ELSE 0 END)
MEMBER [Есть Мера1 Месяц3] AS (CASE WHEN [Мера1 Месяц3] > 0 THEN 1  ELSE 0 END)
MEMBER [Количество Есть Мера1] as ([Есть Мера1 Месяц1] + [Есть Мера1 Месяц2] + [Есть Мера1 Месяц3])	
MEMBER [Measures].[Сред Мера1 3 пред мес] AS
	(CASE WHEN ([Measures].[Количество Есть Мера1])<>0 
	THEN ([Мера1 Месяц1] + [Мера1 Месяц2] + [Мера1 Месяц3]) / 
			[Measures].[Количество Есть Мера1] 
	END)	
	
//Мера2. Аналочично как Мера1
//...

SELECT
        //Мера1
	{([МесяцТекущий], [Measures].[Мера1]),
	([Месяц1], [Measures].[Мера1]),
	([Месяц2], [Measures].[Мера1]),
	([Месяц3], [Measures].[Мера1]),
	([МесяцПрошлогоГода], [Measures].[Мера1]),
	([МесяцТекущий],[Measures].[Сред Мера1 3 пред мес]),
        //Мера2. Аналогично как Мера1
        //...
        }	
ON 0,
NON EMPTY
[SKU].[SKU].[SKU]
ON 1
FROM
	(Select(
	{[Время].[Месяц].&[2017-02-01T00:00:00],
	[Время].[Месяц].&[2017-01-01T00:00:00],
	[Время].[Месяц].&[2016-12-01T00:00:00],
	[Время].[Месяц].&[2016-11-01T00:00:00],
	[Время].[Месяц].&[2016-02-01T00:00:00]}
	) on 0 FROM Profit)


Как тут SET можно заменить на Member? Если заменить, то пишет "Иерархия "Measures" в кортеже появляется более одного раза".
ShIgorзачем использовать функцию SUM? (сумма значений массива из одного элемента равна значению этого элемента)
В запросе выше, если убрать SUM, то работает не корректно. Или как правильно?
...
Рейтинг: 0 / 0
Логика расчета
    #39415357
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ferzmikkMDX-запрос по каждой SKU выгружает вычисляемую меру. Суть в том, что если выгружаемый месяц является текущим или предыдущим, то расчет по формуле, если месяц позапрошлый или ранее то просто выгружается мера без расчетов. Пытаюсь сообразить как это сделать.

Нужно условие как то правильно написать, типа
Код: sql
1.
[Текущий месяц].CurrrentMember = [Анализируемый месяц].CurrrentMember 

Хотя по логике CurrentSet нужен, но не существует в MDX.

Как правильно написать?
И с этим разобраться бы
...
Рейтинг: 0 / 0
Логика расчета
    #39415991
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ShIgorferzmikkВ один сет заталкиваю один месяц как переменную, потом во второй сет как вторую переменную
почему сет, а не мембер?
Разве в MEMBER можно затолкать только месяц? Насколько я правильно понимаю можно затолкать месяц с какой то мерой.
...
Рейтинг: 0 / 0
Логика расчета
    #39415995
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ShIgorferzmikk,

Не вникая в задачу...
во всех расчетах везде указан конкретный член, поэтому не понимаю 2х вещей, зачем объявлять сеты из одного члена, причем не рекомендованным способом
А рекомендованным способом здесь это как?
...
Рейтинг: 0 / 0
Логика расчета
    #39415998
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ShIgorferzmikkВ один сет заталкиваю один месяц как переменную, потом во второй сет как вторую переменную
почему сет, а не мембер?
Пример. Вот простой MDX-запрос
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
WITH
SET[Январь 2017] AS [Время].[Месяц].&[2017-01-01T00:00:00]
MEMBER [Вычисляемая мера] AS SUM([Январь 2017],[Measures].[Отгрузки шт])
SELECT
[Вычисляемая мера]  ON 0,
[Города].[Город].[Город]
ON 1
FROM
PROFIT

Получаю нормальный результат

Потом вместо SET пишу MEMBER
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
WITH
MEMBER[Январь 2017] AS [Время].[Месяц].&[2017-01-01T00:00:00]
MEMBER [Вычисляемая мера] AS SUM([Январь 2017],[Measures].[Отгрузки шт])
SELECT
[Вычисляемая мера]  ON 0,
[Города].[Город].[Город]
ON 1
FROM
PROFIT

Получаю результат по всем месяцам

Как правильно через меру задавать месяц тогда?
...
Рейтинг: 0 / 0
Логика расчета
    #39416023
ShIgor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ferzmikk,
в сторону:
все проблемы от того, что Вы как-то пытаетесь писать запросы MDX не изучая его вообще.
тут что-то подсмотрели, там что-то подсказали, получилось - хорошо, не получилось еще попробую, а основ-то не хватает.

по сути:
членов (member) можно создавать не только в измерении measures (да, да это тоже измерение, как это ни странно)
правильный синтаксис with member [dimension.hierarchy.]member, если не указываете измерение и иерархию, то подразумевается measures.
отсюда, для второго запроса можно даже написать ...select {[Январь 2017], [Вычисляемая мера]} on 0, т.к. они принадлежат одному измерению. но здесь ошибка в том, что SUM в [Вычисляемая мера] суммирует измерение measures, т.е. [Январь 2017] + [Measures].[Отгрузки шт], а [Январь 2017] раскрывается до ([Время].[Месяц].&[2017-01-01T00:00:00], Measures.CurrentMember), поэтому это отгрузки не за январь, а за все время + что-то лишнее.

все вышесказанное приводит к след запросу:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
WITH
MEMBER [Время].[Месяц].[Январь 2017] AS [Время].[Месяц].&[2017-01-01T00:00:00]
MEMBER [Вычисляемая мера] AS ([Январь 2017], [Measures].[Отгрузки шт])
SELECT
[Вычисляемая мера]  ON 0,
[Города].[Город].[Город]
ON 1
FROM
PROFIT



по все остальным вопросам разжевывать если честно лень - это все (включая этот пост) основы.
...
Рейтинг: 0 / 0
Логика расчета
    #39416191
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ShIgorчленов (member) можно создавать не только в измерении measures (да, да это тоже измерение, как это ни странно)
правильный синтаксис with member [dimension.hierarchy.]member, если не указываете измерение и иерархию, то подразумевается measures.
отсюда, для второго запроса можно даже написать ...select {[Январь 2017], [Вычисляемая мера]} on 0, т.к. они принадлежат одному измерению. но здесь ошибка в том, что SUM в [Вычисляемая мера] суммирует измерение measures, т.е. [Январь 2017] + [Measures].[Отгрузки шт], а [Январь 2017] раскрывается до ([Время].[Месяц].&[2017-01-01T00:00:00], Measures.CurrentMember), поэтому это отгрузки не за январь, а за все время + что-то лишнее.
Если для Set запись [Январь 2017]. Item(0).Lag(2) работает, то для Меры не работает. Работает, если меру еще так написать [Январь 2017]. Item(0)
Получается для меры уже нельзя обратиться к предыдущему периоду. Верно? Или можно обратиться к предыдущему, но по другому надо записывать?
...
Рейтинг: 0 / 0
Логика расчета
    #39416253
ShIgor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ferzmikk,

1. не путайте меру (measure) и члена (member)!!! (для измерения measures это допустимо, для других нет)

2. да, Lag не будет работать с вычисляемыми членами, к тому же она работает не с набором (set), а с уровнем иерархии указанного члена.

3. если Вам нравится работать с наборами - пожалуйста, разве кто ограничивает?
и сравнение в этом случае вы сделаете просто [Текущий месяц].Item(0) is [Анализируемый месяц].Item(0)
да и сумму выкиньте все-равно т.к.
SUM([Анализируемый месяц], [Measures].[Мера1]) = ([Анализируемый месяц].Item(0), [Measures].[Мера1])
...
Рейтинг: 0 / 0
Логика расчета
    #39416589
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ShIgorсравнение в этом случае вы сделаете просто [Текущий месяц].Item(0) is [Анализируемый месяц].Item(0)
Провожу эксперимент
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
WITH
SET [Базовый Анализируемый месяц]  AS [Время].[Месяц].&[2017-03-01T00:00:00] 
SET [Предыдущий анализируемый месяц] AS [Время].[Месяц].&[2017-02-01T00:00:00]
MEMBER [Measures].[Вычисляемое поле] AS
	(CASE WHEN [Базовый Анализируемый месяц].Item(0) IS  [Предыдущий анализируемый месяц].Item(0) THEN
		1
	ELSE
		2
	END)
SELECT
	[Measures].[Вычисляемое поле] ON 0,
NON EMPTY
	[SKU].[SKU].[SKU]	ON 1
FROM
	(SELECT([Время].[Месяц].&[2016-11-01T00:00:00]:[Время].[Месяц].&[2016-12-01T00:00:00]) ON 0 FROM Profit)


В результате отображаются единицы, а не двойки. Что тут пропущено?
...
Рейтинг: 0 / 0
Логика расчета
    #39416629
ShIgor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ferzmikk,

ищите своих тараканов сами
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
WITH
SET [Базовый]  AS [Date].[Calendar Year].&[2009] 
SET [Предыдущий] AS [Date].[Calendar Year].&[2009]
MEMBER [Measures].[Вычисляемое поле] AS
	(CASE WHEN [Базовый].Item(0) IS  [Предыдущий].Item(0) THEN 1 ELSE 2 END)
member [БазовыйИмя] as [Базовый].Item(0).Name
member [ПредыдущийИмя] as [Предыдущий].Item(0).Name
SELECT
	{[Measures].[Вычисляемое поле], [БазовыйИмя], [ПредыдущийИмя]} ON 0

FROM 
(SELECT ([Date].[Calendar Year].&[2008]:[Date].[Calendar Year].&[2009]) ON 0 FROM [Adventure Works])


Вычисляемое поле БазовыйИмя ПредыдущийИмя1 CY 2009 CY 2009

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
WITH
SET [Базовый]  AS [Date].[Calendar Year].&[2009] 
SET [Предыдущий] AS [Date].[Calendar Year].&[2008]
MEMBER [Measures].[Вычисляемое поле] AS
	(CASE WHEN [Базовый].Item(0) IS  [Предыдущий].Item(0) THEN 1 ELSE 2 END)
member [БазовыйИмя] as [Базовый].Item(0).Name
member [ПредыдущийИмя] as [Предыдущий].Item(0).Name
SELECT
	{[Measures].[Вычисляемое поле], [БазовыйИмя], [ПредыдущийИмя]} ON 0

FROM 
(SELECT ([Date].[Calendar Year].&[2008]:[Date].[Calendar Year].&[2009]) ON 0 FROM [Adventure Works])


Вычисляемое поле БазовыйИмя ПредыдущийИмя2 CY 2009 CY 2008

и научитесь уже ставить правильные скобки в нужных местах, в вашем коде легко не только человеку запутаться.
...
Рейтинг: 0 / 0
Логика расчета
    #39416646
ShIgor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ferzmikk,

это Ваш запрос:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
WITH
SET [Базовый]  AS [Date].[Calendar Year].&[2009]
SET [Предыдущий] AS [Date].[Calendar Year].&[2008]
MEMBER [Measures].[Вычисляемое поле] AS
	(CASE WHEN [Базовый].Item(0) IS  [Предыдущий].Item(0) THEN 1 ELSE 2 END)
member [БазовыйИмя] as [Базовый].Item(0).Name
member [ПредыдущийИмя] as [Предыдущий].Item(0).Name
SELECT
	{[Measures].[Вычисляемое поле], [БазовыйИмя], [ПредыдущийИмя]} ON 0
FROM 
(SELECT ([Date].[Calendar Year].&[2006]:[Date].[Calendar Year].&[2007]) ON 0 FROM [Adventure Works])



Вычисляемое поле БазовыйИмя ПредыдущийИмя1 (null) (null)
...
Рейтинг: 0 / 0
Логика расчета
    #39416875
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ShIgorferzmikk,

это Ваш запрос:
Код: sql
1.
...



Вычисляемое поле БазовыйИмя ПредыдущийИмя1 (null) (null)
Период в субкубе неправильно написал и из за этого ошибка.


А если надо два элемента сравнивать больше или меньше.
Код: sql
1.
(CASE WHEN [Базовый].Item(0) >  [Предыдущий].Item(0) THEN 1 ELSE 2 END)


То надо через Member делать?
...
Рейтинг: 0 / 0
Логика расчета
    #39417024
ShIgor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ferzmikk,

почитайте наконец документацию хотя бы. вариантов несколько и все зависит от ситуации.
видите же сами, моя рекомендация использовать членов Вам не подошла. здесь ситуация так же.
на вскидку - можно сравнивать позицию внутри иерархии, можно значение (member value), а можно наименование в т.ч. приведенное к нужному типу, связанный атрибут, ключ, а может Вам надо сравнивать конкретную меру...
...
Рейтинг: 0 / 0
Логика расчета
    #39418708
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ShIgorferzmikk,
почитайте наконец документацию хотя бы.Читать начал.
вариантов несколько и все зависит от ситуации.
видите же сами, моя рекомендация использовать членов Вам не подошла. здесь ситуация так же.
на вскидку - можно сравнивать позицию внутри иерархии, можно значение (member value), а можно наименование в т.ч. приведенное к нужному типу, связанный атрибут, ключ, а может Вам надо сравнивать конкретную меру...
Сразу опишу задачу в целом и не упрощая, чтобы не затягиваться. Хотя MDX-запрос получился очень длинным. И если посмотреть со структуры, то тут ничего сложного нет. Логика тут в том, что анализируемый месяц определяется: является ли текущим месяцем, предыдущим, позапрошлым или еще ранее. Исходя из этого подбирается формула для [Вычисляемая мераM Анализируемый месяцN], где M это номер меры и N это номер месяца.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
WITH
//Задаем анализируемые месяцы. После AS используются в качестве параметров
SET [Анализируемый месяц1] AS [Время].[Месяц].&[2017-03-01T00:00:00]
SET [Анализируемый месяц2] AS [Время].[Месяц].&[2017-02-01T00:00:00]
SET [Анализируемый месяц3] AS [Время].[Месяц].&[2016-12-01T00:00:00]

//Текущий месяц
SET [Текущий месяц] AS
	StrToMember("[Время].[Месяц].&[" + VBA!Format(VBA!Dateadd('m', 0, VBA!Now()), 'yyyy-MM-01T00:00:00') + "]")
MEMBER [Время].[Месяц].[Текущий месяц] AS [Текущий месяц]

//Эти анализируемые базовые месяцы толкаем в MEMBER
MEMBER [Время].[Месяц].[Анализируемый базовый месяц1] AS [Анализируемый базовый месяц1]
MEMBER [Время].[Месяц].[Анализируемый базовый месяц2] AS [Анализируемый базовый месяц2]
MEMBER [Время].[Месяц].[Анализируемый базовый месяц3] AS [Анализируемый базовый месяц3]

//Эти анализируемые предыдущие месяцы толкаем в MEMBER
MEMBER [Время].[Месяц].[Анализируемый предыдущий месяц1] AS [Анализируемый базовый месяц1].Item(0).Lag(1)
MEMBER [Время].[Месяц].[Анализируемый предыдущий месяц2] AS [Анализируемый базовый месяц2].Item(0).Lag(1)
MEMBER [Время].[Месяц].[Анализируемый предыдущий месяц3] AS [Анализируемый базовый месяц3].Item(0).Lag(1)

//Эти анализируемые позапрошлые месяцы толкаем в MEMBER
MEMBER [Время].[Месяц].[Анализируемый позапрошлый месяц1] AS [Анализируемый базовый месяц1].Item(0).Lag(2)
MEMBER [Время].[Месяц].[Анализируемый позапрошлый месяц2] AS [Анализируемый базовый месяц2].Item(0).Lag(2)
MEMBER [Время].[Месяц].[Анализируемый позапрошлый месяц3] AS [Анализируемый базовый месяц3].Item(0).Lag(2)

//Меры для Анализируемого базового месяца
MEMBER [Основная Мера Анализируемый базовый месяц1] AS ([Анализируемый базовый месяц1], [Основная мера])
MEMBER [Мера1 Анализируемый базовый месяц1] AS ([Анализируемый базовый месяц1], [Мера1])
MEMBER [Мера2 Анализируемый базовый месяц1] AS ([Анализируемый базовый месяц1], [Мера2])
MEMBER [Мера3 Анализируемый базовый месяц1] AS ([Анализируемый базовый месяц1], [Мера3])

//Меры для Анализируемого предыдущего месяца
MEMBER [Основная Мера Анализируемый предыдущий месяц1] AS ([Анализируемый предыдущий месяц1], [Основная мера])
MEMBER [Мера1 Анализируемый предыдущий месяц1] AS ([Анализируемый предыдущий месяц1], [Мера1])
MEMBER [Мера2 Анализируемый предыдущий месяц1] AS ([Анализируемый предыдущий месяц1], [Мера2])
MEMBER [Мера3 Анализируемый предыдущий месяц1] AS ([Анализируемый предыдущий месяц1], [Мера3])

//Меры для Анализируемого позапрошлого месяца
MEMBER [Основная Мера Анализируемый позапрошлый месяц1] AS ([Анализируемый позапрошлый месяц1], [Основная мера])
MEMBER [Мера1 Анализируемый позапрошлый месяц1] AS ([Анализируемый позапрошлый месяц1], [Мера1])
MEMBER [Мера2 Анализируемый позапрошлый месяц1] AS ([Анализируемый позапрошлый месяц1], [Мера2])
MEMBER [Мера3 Анализируемый позапрошлый месяц1] AS ([Анализируемый позапрошлый месяц1], [Мера3])


MEMBER [Вычисляемая мера1 Анализируемый базовый месяц1] AS
    CASE WHEN Если [Анализируемый базовый месяц1] это текущий месяц
            CASE WHEN Если [Мера1 Анализируемый предыдущий месяц1]  <> 0, ТО
                   CASE WHEN [Основная мера Анализируемый предыдущий месяц1] <> 0, ТО
                        [Основная мера Анализируемый базовый месяц1] * 
                             [Мера1 Анализируемый предыдущий месяц1] /  [Основная мера Анализируемый предыдущий месяц1]
                   END)
            ELSE
                   CASE WHEN [Основная мера Анализируемый позапрошлый месяц1] <>0, ТО
                        [Основная мера Анализируемый базовый месяц1] * 
                             [Мера1 Анализируемый позапрошлый месяц1] /  [Основная мера Анализируемый позапрошлый месяц1]
                   END)
            END)
    WHEN Если [Анализируемый базовый месяц1] это предыдущий от текущего месяца
            CASE WHEN Если  [Основная мера Анализируемый позапрошлый месяц1] <>0, ТО
                       [Основная мера Анализируемый базовый месяц1] *
                             [Мера1 Анализируемый позапрошлый месяц1] /  [Основная мера Анализируемый позапрошлый месяц1]
            END)
    WHEN Если [Анализируемый базовый месяц] это позапрошлый или ранее от текущего месяца
            [Мера1 Анализируемый позапрошлый месяц1]
    END)

//Аналогично как и [Вычисляемая мера1 Анализируемый базовый месяц1], но тот же Анализируемый период1
MEMBER [Вычисляемая мера2 Анализируемый базовый месяц1] AS
    CASE WHENЕсли [Анализируемый базовый месяц1] это текущий месяц
              CASE WHEN Если [Мера2 Анализируемый предыдущий месяц1]  <> 0, ТО
                   CASE WHEN [Основная мера Анализируемый предыдущий месяц1] <> 0, ТО
                        [Основная мера Анализируемый базовый месяц1] * 
                             [Мера2 Анализируемый предыдущий месяц1] /  [Основная мера Анализируемый предыдущий месяц1]
                   END)
            ELSE
                   CASE WHEN [Основная мера Анализируемый позапрошлый месяц1] <>0, ТО
                        [Основная мера Анализируемый базовый месяц1] * 
                             [Мера2 Анализируемый позапрошлый месяц1] /  [Основная мера Анализируемый позапрошлый месяц1]
                   END)
            END)
    WHEN Если [Анализируемый базовый месяц1] это предыдущий от текущего месяца
            CASE WHEN Если  [Основная мера Анализируемый позапрошлый месяц1] <>0, ТО
                       [Основная мера Анализируемый базовый месяц1] *
                             [Мера2 Анализируемый позапрошлый месяц1] /  [Основная мера Анализируемый позапрошлый месяц1]
            END)
    WHEN Если [Анализируемый базовый месяц] это позапрошлый или ранее от текущего месяца
            [Мера2 Анализируемый позапрошлый месяц1]
    END)
MEMBER [Вычисляемая мера3 Анализируемый месяц1] AS ...

//Аналогично как и [Вычисляемая мера1 Аналогичный базовый месяц1], но другой Анализируемый период2
MEMBER [Вычисляемая мера1 Анализируемый месяц2] AS
    CASE WHEN Если [Анализируемый базовый месяц2] это текущий месяц
                 CASE WHEN Если [Мера1 Анализируемый предыдущий месяц2]  <> 0, ТО
                   CASE WHEN [Основная мера Анализируемый предыдущий месяц2] <> 0, ТО
                        [Основная мера Анализируемый базовый месяц2] * 
                             [Мера1 Анализируемый предыдущий месяц2] /  [Основная мера Анализируемый предыдущий месяц2]
                   END)
            ELSE
                   CASE WHEN [Основная мера Анализируемый позапрошлый месяц2] <>0, ТО
                        [Основная мера Анализируемый базовый месяц2] * 
                             [Мера1 Анализируемый позапрошлый месяц2] /  [Основная мера Анализируемый позапрошлый месяц2]
                   END)
            END)
    WHEN Если [Анализируемый базовый месяц2] это предыдущий от текущего месяца
            CASE WHEN Если  [Основная мера Анализируемый позапрошлый месяц2] <>0, ТО
                       [Основная мера Анализируемый базовый месяц2] *
                             [Мера1 Анализируемый позапрошлый месяц2] /  [Основная мера Анализируемый позапрошлый месяц2]
            END)
    WHEN Если [Анализируемый базовый месяц2] это позапрошлый или ранее от текущего месяца
            [Мера1 Анализируемый позапрошлый месяц2]
    END)
//Аналогично
MEMBER [Вычисляемая мера2 Анализируемый месяц2] AS ...
MEMBER [Вычисляемая мера3 Анализируемый месяц2] AS ...

//Аналогично для Анализируемого месяца3
MEMBER [Вычисляемая мера1 Анализируемый месяц3] AS ...
MEMBER [Вычисляемая мера2 Анализируемый месяц3] AS ...
MEMBER [Вычисляемая мера3 Анализируемый месяц3] AS ...

//Делаем последующие расчеты
MEMBER [Еще вычисляемая мера Анализируемый месяц1] AS   [Основная Мера Анализируемый базовый месяц1] 
                   - [Вычисляемая мера1 Анализируемый месяц1] 
                   - [Вычисляемая мера2 Анализируемый месяц1] 
                   - [Вычисляемая мера3 Анализируемый месяц1] 
MEMBER [Еще вычисляемая мера Анализируемый месяц2] AS   [Основная Мера Анализируемый базовый  месяц2] 
                   - [Вычисляемая мера1 Анализируемый месяц2] 
                   - [Вычисляемая мера2 Анализируемый месяц2] 
                   - [Вычисляемая мера3 Анализируемый месяц2] 
MEMBER [Еще вычисляемая мера Анализируемый месяц3] AS   [Основная Мера Анализируемый базовый  месяц3] 
                   - [Вычисляемая мера1 Анализируемый месяц3] 
                   - [Вычисляемая мера2 Анализируемый месяц3] 
                   - [Вычисляемая мера3 Анализируемый месяц3] 
SELECT
...

Такая вот логика

1. Для данной задачи все таки месяцы лучше толкать в Set или в MEMBER?

2. Теперь имея полный код как правильно записать записи для выделенных строк в MDX-запросе? Учитывая, что если, например, сравнивать [Анализируемый базовый месяцN] с позапрошлым или ранее от текущего месяца , то IS не подойдет.

3. Логичнее тут использовать пользовательские функции для [Вычисляемая мераM Анализируемый месяцN], чтобы упростить MDX.
...
Рейтинг: 0 / 0
Логика расчета
    #39423242
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В общем, удалось написать. Получил нужный результат. Запрос получился насыщенным.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
WITH
//В данной задаче задаются два анализируемых месяца: Базовый месяц1 и Базовый Месяц2
//Например, Январь 2017 и Март 2017. Для каждого анализируемого месяца в зависимости от того, какой сейчас текущий месяц
//проводится расчет для каждого Мера1 и Мера2.
//В расчете для каждого анализируемого месяца подтягиваются нужные исторические месяцы (предыдущий, позапрошлый).

//Задаем анализируемые месяцы в каждый сет.
SET [Анализ. базовый месяц1] AS [Время].[Месяц].&[2017-01-01T00:00:00].Item(0)
SET [Анализ. предыдущий месяц1] AS [Анализируемый базовый месяц1].Item(0).Lag(1)
SET [Анализ. позапрошлый месяц1] AS [Анализируемый базовый месяц1].Item(0).Lag(2) 

SET [Анализ. базовый месяц2] AS [Время].[Месяц].&[2017-03-01T00:00:00].Item(0)
SET [Анализ. предыдущий месяц2] AS [Анализируемый базовый месяц2].Item(0).Lag(1)
SET [Анализ. позапрошлый месяц2] AS [Анализируемый базовый месяц2].Item(0).Lag(2) 

//Переводим в MEMBER.
MEMBER [Время].[Месяц].[Анализируемый базовый месяц1] AS [Анализ. базовый месяц1].Item(0)
MEMBER [Время].[Месяц].[Анализируемый предыдущий месяц1] AS [Анализ. базовый месяц1].Item(0).Lag(1)
MEMBER [Время].[Месяц].[Анализируемый позапрошлый месяц1] AS [Анализ. базовый месяц1].Item(0).Lag(2)

MEMBER [Время].[Месяц].[Анализируемый базовый месяц2] AS [Анализ. базовый месяц2].Item(0)
MEMBER [Время].[Месяц].[Анализируемый предыдущий месяц2] AS [Анализ. базовый месяц2].Item(0).Lag(1)
MEMBER [Время].[Месяц].[Анализируемый позапрошлый месяц2] AS [Анализ. базовый месяц2].Item(0).Lag(2)
	
//Текущий месяц как сет
SET [Текущий месяц] AS
	StrToMember("[Время].[Месяц].&[" + VBA!Format(VBA!Dateadd('m', 0, VBA!Now()), 'yyyy-MM-01T00:00:00') + "]")

//Эти периоды как меры, указывают месяцы в анализируемых периодах.
MEMBER [Measures].[Анализируемая базовая Дата1] AS VBA!DATESERIAL(
	VBA!MID([Анализ. базовый месяц].Item(0).UniqueName,19,4),
	VBA!MID([Анализ. базовый месяц].Item(0).UniqueName,24,2),
	1)
MEMBER [Measures].[Анализируемая базовая Дата2] AS VBA!DATESERIAL(
	VBA!MID([Анализ. базовый месяц].Item(0).UniqueName,19,4),
	VBA!MID([Анализ. базовый месяц].Item(0).UniqueName,24,2),
	1)

//Периоды для сравнения. Эти периоды как меры указывают, который текущий, предыдущий и позапрошлый месяц.
MEMBER [Measures].[Текущая Дата] AS VBA!DATESERIAL(
	VBA!MID([Текущий месяц].Item(0).UniqueName,19,4),
	VBA!MID([Текущий месяц].Item(0).UniqueName,24,2),
	1)
//Верхнюю запись по логике можно написать по короче как ниже, но почему то не работает.
//MEMBER [Measures].[Текущая Дата] AS VBA!Format(VBA!Dateadd('m', 0, VBA!Now()), '01.MM.yyyy')
MEMBER [Measures].[Предыдущая Дата] AS VBA!DateAdd('m', -1, [Текущая Дата])
MEMBER [Measures].[Позапрошлая Дата] AS VBA!DateAdd('m', -2, [Текущая Дата])

MEMBER [Вычисляемая мера1 Анализируемый базовый месяц1] AS
	(CASE WHEN [Анализируемая базовая Дата1] = [Текущая Дата] THEN
		(CASE WHEN ([Анализируемый предыдущий месяц1], [Мера1]) <>0 THEN
			(CASE WHEN ([Анализируемый предыдущий месяц1],[Основная мера])<>0  THEN
				([Анализируемый базовый месяц1], [Основная мера]) * 
				([Анализируемый предыдущий месяц1], [Мера1]) /
				([Анализируемый предыдущий месяц1], [Основная мера])
			END)
		ELSE
			(CASE WHEN ([Анализируемый позапрошлый месяц1],[Основная мера])<>0  THEN
				([Анализируемый базовый месяц1], [Основная мера]) * 
				([Анализируемый позапрошлый месяц1], [Мера1]) /
				([Анализируемый позапрошлый месяц1], [Основная мера])
			END)
		END)		
	WHEN [Анализируемая базовая Дата1] = [Предыдущая Дата] THEN
		(CASE WHEN ([Анализируемый предыдущий месяц1],[Основная мера])<>0  THEN
				([Анализируемый базовый месяц1], [Основная мера]) * 
				([Анализируемый предыдущий месяц1], [Мера1]) /
				([Анализируемый предыдущий месяц1], [Основная мера])
			END)
	WHEN [Анализируемая базовая Дата1] <= [Позапрошлая Дата]  THEN
		([Анализируемый базовый месяц1], [Мера1])	
	ELSE
		NULL
	END)

//Аналогично
MEMBER [Вычисляемая мера2 Анализируемый базовый месяц1] AS ...
MEMBER [Вычисляемая мера1 Анализируемый базовый месяц2] AS ...
MEMBER [Вычисляемая мера2 Анализируемый базовый месяц2] AS ...
...


Хотелось было получить Ваши комментарий по данному MDX-запросу. Как оцениваете идею решения данной задачи, а именно, сравнение анализируемого месяца с текущим месяцем? Что тут лишнее?
...
Рейтинг: 0 / 0
Логика расчета
    #39423275
ShIgor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ferzmikk,

С предыдущего Вашего поста хотел описать но, времени не хватает продемонстрировать, чтоб не быть голословным.
Однако все-таки придется..

Если я правильно понял:
а. у Вас есть набор анализируемых месяцев (в т.ч. возможно текущий)
б. у каждого из них есть еще предыдущий к анализируемому и позапрошлый к анализироемому.
в. есть "основная мера" и "мера1", которые участвуют в расчете
г. расчет зависит от текущего месяца, предыдущего к текущему и позапрошлого от текущего (главное здесь "текущий", а не анализируемый так?)

итог: все сводится к одному набору месяцев и единственной вычисляемой мере.

и я так понимаю, Вы просто детализировали каждый шаг вычисления чтоб самому себе было понятнее что к чему.
С одной стороны это нормально (при сложных последовательных операциях я тоже так делаю, иначе легко запутаться), с другой стороны, окончательный запрос слишком "жесткий" и поправить в нем что-либо становится проблематичным.
...
Рейтинг: 0 / 0
Логика расчета
    #39423631
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ShIgorferzmikk,

Если я правильно понял:
а. у Вас есть набор анализируемых месяцев (в т.ч. возможно текущий)
б. у каждого из них есть еще предыдущий к анализируемому и позапрошлый к анализироемому.
в. есть "основная мера" и "мера1", которые участвуют в расчете
г. расчет зависит от текущего месяца, предыдущего к текущему и позапрошлого от текущего (главное здесь "текущий", а не анализируемый так?)

итог: все сводится к одному набору месяцев и единственной вычисляемой мере.
В общем, опишу задачу по яснее.

Есть Мера1 и Мера2. В кубе эти меры заложены так, что если сейчас Март 2017 г (то есть текущий месяц) и выгружаем за Январь 2017 Меру1, то выгружаем просто фактическую Меру1. Но если выгружать за февраль 2017 или март 2017 (даже если не полный март 2017), то тут надо не фактическую Меру1 выгружать, а расчетную. Аналогично для Меры2.

Есть два анализируемых месяца для каждой меры. Каждый анализируемый период заглядывает предыдущий и позапрошлый месяц от анализируемого месяца в зависимости от того, какой текущий месяц. Используются три меры: Мера1, Мера2 и Общая мера. Получаются 4 формулы: [Вычисляемая мера N , Анализируемый месяц M ].

Логика заключается в том, что можно анализировать разные месяцы. Если эти месяцы ранние, то выгружаются просто фактические данные, если это анализируемый месяц является текущим или предыдущим от текущего месяца, то тут расчет проводится по формуле. См. скриншот.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
//Ниже пример, при условии что текущий месяц это Март 2017 г,
//иначе пришлось писать универсально, то есть текущий, предыдущий, позапрошлый месяц как в предыдущем посте

MEMBER  [Вычисляемая мера1, Анализируемый месяц1] AS
    ЕСЛИ [Анализируемый месяц1] есть текущий месяц (то есть Март 2017), то 
            ЕСЛИ [Мера1, ФЕВРАЛЬ 2017]  <> 0, ТО
                   [Общая мера, МАРТ 2017]   *   [Мера1, ФЕВРАЛЬ 2017]   /   [Общая мера, ФЕВРАЛЬ 2017]
            ИНАЧЕ
                   [Общая мера, МАРТ 2017]   *   [Мера1, ЯНВАРЬ 2017]   /   [Общая мера, ЯНВАРЬ 2017]
            КОНЕЦ ЕСЛИ
    ИНАЧЕ ЕСЛИ [Анализируемый месяц1]  есть предыдущий месяц от текущего ( то есть февраль 2017), то
            [Общая мера, Февраль 2017]   *   [Мера1, ЯНВАРЬ 2017]   /   [Общая мера, ЯНВАРЬ 2017]        
    ИНАЧЕ ЕСЛИ [Анализируемый месяц1]  есть позапрошлый от текущего месяца (то есть Январь 2017) или ранее, то
            //Выгружается только фактическая
           [Мера1, ЯНВАРЬ 2017]
    ИНАЧЕ
           NULL
    КОНЕЦ ЕСЛИ

MEMBER  [Вычисляемая мера1, Анализируемый месяц2] AS
    ЕСЛИ [Анализируемый месяц2] есть текущий месяц (то есть Март 2017), то 
            ЕСЛИ [Мера1, ФЕВРАЛЬ 2017]  <> 0, ТО
                   [Общая мера, МАРТ 2017]   *   [Мера1, ФЕВРАЛЬ 2017]   /   [Общая мера, ФЕВРАЛЬ 2017]
            ИНАЧЕ
                   [Общая мера, МАРТ 2017]   *   [Мера1, ЯНВАРЬ 2017]   /   [Общая мера, ЯНВАРЬ 2017]
            КОНЕЦ ЕСЛИ
    ИНАЧЕ ЕСЛИ [Анализируемый месяц2]  есть предыдущий месяц от текущего ( то есть февраль 2017), то
            [Общая мера, Февраль 2017]   *   [Мера1, ЯНВАРЬ 2017]   /   [Общая мера, ЯНВАРЬ 2017]        
    ИНАЧЕ ЕСЛИ [Анализируемый месяц2]  есть позапрошлый от текущего месяца (то есть Январь 2017) или ранее, то
            //Выгружается только фактическая
           [Мера1, ЯНВАРЬ 2017]
    ИНАЧЕ
           NULL
    КОНЕЦ ЕСЛИ

MEMBER  [Вычисляемая мера2, Анализируемый месяц1] AS
    ЕСЛИ [Анализируемый месяц1] есть текущий месяц (то есть Март 2017), то 
            ЕСЛИ [Мера2, ФЕВРАЛЬ 2017]  <> 0, ТО
                   [Общая мера, МАРТ 2017]   *   [Мера2, ФЕВРАЛЬ 2017]   /   [Общая мера, ФЕВРАЛЬ 2017]
            ИНАЧЕ
                   [Общая мера, МАРТ 2017]   *   [Мера2, ЯНВАРЬ 2017]   /   [Общая мера, ЯНВАРЬ 2017]
            КОНЕЦ ЕСЛИ
    ИНАЧЕ ЕСЛИ [Анализируемый месяц1]  есть предыдущий месяц от текущего ( то есть февраль 2017), то
            [Общая мера, Февраль 2017]   *   [Мера2, ЯНВАРЬ 2017]   /   [Общая мера, ЯНВАРЬ 2017]        
    ИНАЧЕ ЕСЛИ [Анализируемый месяц1]  есть позапрошлый от текущего месяца (то есть Январь 2017) или ранее, то
            //Выгружается только фактическая
           [Мера2, ЯНВАРЬ 2017]
    ИНАЧЕ
           NULL
    КОНЕЦ ЕСЛИ

MEMBER  [Вычисляемая мера2, Анализируемый месяц2] AS
    ЕСЛИ [Анализируемый месяц2] есть текущий месяц (то есть Март 2017), то 
            ЕСЛИ [Мера2, ФЕВРАЛЬ 2017]  <> 0, ТО
                   [Общая мера, МАРТ 2017]   *   [Мера2, ФЕВРАЛЬ 2017]   /   [Общая мера, ФЕВРАЛЬ 2017]
            ИНАЧЕ
                   [Общая мера, МАРТ 2017]   *   [Мера2, ЯНВАРЬ 2017]   /   [Общая мера, ЯНВАРЬ 2017]
            КОНЕЦ ЕСЛИ
    ИНАЧЕ ЕСЛИ [Анализируемый месяц2]  есть предыдущий месяц от текущего ( то есть февраль 2017), то
            [Общая мера, Февраль 2017]   *   [Мера2, ЯНВАРЬ 2017]   /   [Общая мера, ЯНВАРЬ 2017]        
    ИНАЧЕ ЕСЛИ [Анализируемый месяц2]  есть позапрошлый от текущего месяца (то есть Январь 2017) или ранее, то
            //Выгружается только фактическая
           [Мера2, ЯНВАРЬ 2017]
    ИНАЧЕ
           NULL
    КОНЕЦ ЕСЛИ


Похоже тут не обойтись без пользовательской функции, который принимает два параметра: Мера и Анализируемый период. Возможно надо будет еще параметр Общая Мера.

Или тут можно попроще написать?
...
Рейтинг: 0 / 0
Логика расчета
    #39423637
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ShIgorferzmikk,

С предыдущего Вашего поста хотел описать но, времени не хватает продемонстрировать, чтоб не быть голословным.
Однако все-таки придется..

Если я правильно понял:
а. у Вас есть набор анализируемых месяцев (в т.ч. возможно текущий)В данном примере для простоты представлены два анализируемых месяца и текущий месяц для сравнения. А в реальном примере 5 анализируемых месяцев и 4 меры. И причем расчеты немного отличаются для каждой меры, но идентичны для каждого анализируемого месяца. б. у каждого из них есть еще предыдущий к анализируемому и позапрошлый к анализируемому.
в. есть "основная мера" и "мера1", которые участвуют в расчетеЕще Мера2г. расчет зависит от текущего месяца, предыдущего к текущему и позапрошлого от текущего (главное здесь "текущий", а не анализируемый так?)Пример, Текущий месяц это Март 2017 год. Анализируемый месяц1 это Ноябрь 2016, а анализируемый месяц2 это Февраль 2017.итог: все сводится к одному набору месяцев и единственной вычисляемой мере.И как это выглядит?и я так понимаю, Вы просто детализировали каждый шаг вычисления чтоб самому себе было понятнее что к чему.
С одной стороны это нормально (при сложных последовательных операциях я тоже так делаю, иначе легко запутаться), с другой стороны, окончательный запрос слишком "жесткий" и поправить в нем что-либо становится проблематичным.Почему слишком "жесткий"? Он же структурированный, что не придется ломать весь код.


В общем расчет хитрый, но задачка интересная. Возможно для такой задачи можно не усложнять, а попроще написать.
...
Рейтинг: 0 / 0
Логика расчета
    #39424125
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Такой вопрос
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
WITH
MEMBER [Вычисляемая мера] AS ([Время].[Месяц].&[2017-02-01T00:00:00], [Measures].[Мера2])
SELECT
    {([Время].[Месяц].&[2016-02-01T00:00:00], [Measures].[Мера1]),
    ([Время].[Месяц].&[2017-02-01T00:00:00], [Measures].[Мера1]),
    ([Время].[Месяц].&[2016-02-01T00:00:00],[Вычисляемая мера]),
    ([Время].[Месяц].&[2017-02-01T00:00:00],[Вычисляемая мера])
} on 0,
    [Города].[Город].[Город]
ON 1
FROM
    profit


В результате получаем, что для третьей и четвертой колонки значения одинаковые. Я правильно понимаю, что для этих мер указанная дата внутри в скобках после SELECT никак не влияет на результат?


И еще.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
WITH
SET [Сет1] AS [Время].[Месяц].&[2016-02-01T00:00:00]
SET [Сет2] AS [Время].[Месяц].&[2017-02-01T00:00:00]
MEMBER [Время].[Месяц].[Сет1 как мера] AS [Сет1].Item(0)
MEMBER [Время].[Месяц].[Сет2 как мера] AS [Сет2].Item(0)
MEMBER [Вычисляемая мера1] AS ([Сет1 как мера], [Measures].[Мера2])
MEMBER [Вычисляемая мера2] AS ([Сет2 как мера], [Measures].[Мера2])
SELECT
	{([Время].[Месяц].&[2016-02-01T00:00:00], [Measures].[Мера1]),
	([Время].[Месяц].&[2017-02-01T00:00:00], [Measures].[Мера1]),
	([любой сет],[Вычисляемая мера1]),
	([любой сет],[Вычисляемая мера2])} ON 0,
	[Города].[Город].[Город] ON 1
FROM
   Profit


чтобы вместо выделенных строк было так
Код: sql
1.
2.
	([Сет1],[Вычисляемая мера]),
	([Сет2],[Вычисляемая мера])



Это нужно для того, чтобы в результате были нужные названия заголовок (первая строка заголовка месяцы, а вторая строка заголовков - меры). Это возможно сделать?
...
Рейтинг: 0 / 0
Логика расчета
    #39426562
ShIgor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ferzmikk,

1. См картинку. На пальцах понятнее?
2. Как это Вы хотите запихнуть набор в кортеж? Вам нужен конкретный член, а это [Сет1].Item(0)
...
Рейтинг: 0 / 0
Логика расчета
    #39431237
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ShIgorferzmikk,

1. См картинку. На пальцах понятнее?
На картинке понятно. Спасибо!

Но тут поэкспериментировал с данными и потом кое что обнаружил интересное.

Вот такой MDX-запрос. Возьмем для анализа Мера1 и вычисляемую меру Фильтр Предыдущий месяц Мера1. Эта вычисляемая мера рассчитывает сумму Мера1 по всем SKU для соответствующей ТТ. С учетом того, что в результате данные выводим по ТТ, а не по ТТ и SKU.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
WITH
SET [Анализируемый месяц] AS [Время].[Месяц].&[2017-03-01T00:00:00]
MEMBER [Время].[Месяц].[Базовый месяц] AS [Анализируемый месяц].Item(0)
MEMBER [Время].[Месяц].[Предыдущий месяц] AS [Анализируемый месяц].Item(0).Lag(1)	

MEMBER [Вычисляемая мера Предыдущий месяц Мера] AS
	([Предыдущий месяц],[Measures].[Мера])	
		
MEMBER [Фильтр Предыдущий месяц Мера1] AS
	SUM(
		Filter(
			[SKU].[SKU].[SKU],
			([Торговые точки].[Код ТТ].CurrentMember, [Measures].[Мера1])<>0),
		([Предыдущий месяц], [Measures].[Мера1]))
		
SELECT	
{   
	([Предыдущий месяц],       [Measures].[Мера1]),
	([Базовый месяц],          [Measures].[Мера1]),
	([Предыдущий месяц],       [Вычисляемая мера Предыдущий месяц Реализация сумма без НДС]),
	([Базовый месяц],          [Вычисляемая мера Предыдущий месяц Реализация сумма без НДС]),
	([Предыдущий месяц],       [Фильтр Предыдущий месяц Мера1]),
	([Базовый месяц],          [Фильтр Предыдущий месяц Мера1])
}   ON 1,
NON EMPTY
	[Торговые точки].[Код ТТ].[Код ТТ]
	ON 0
FROM 
	(SELECT (
		[Время].[Месяц].&[2017-02-01T00:00:00]:[Время].[Месяц].&[2017-03-01T00:00:00],		
		[Торговые точки].[Код ТТ].[ТТ00001])
		On 0 FROM PROFIT) 


Получаем такой результат
ТТ00001Предыдущий месяцМера1223Базовый месяцМера1236Предыдущий месяцВычисляемая мера Предыдущий месяц Мера1223Базовый месяцВычисляемая мера Предыдущий месяц Мера1223Предыдущий месяцФильтр Предыдущий месяц Мера1223Базовый месяцФильтр Предыдущий месяц Мера1 217
Как видим в третьей и в четвертой строке значение 223, что так и должно быть. Но по последней строке другое значение. По сути якобы значение должно быть 223. Или тут другая логика срабатывает, например, фильтр как то влияет?
...
Рейтинг: 0 / 0
Логика расчета
    #39436961
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как правильно написать, чтобы вместо значения 217 возвращал 223?
...
Рейтинг: 0 / 0
Логика расчета
    #39437585
ShIgor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ferzmikk,

Сейчас в фильтре участвует [Время].[Месяц].CurrentMember, и получается, что результирующий набор SKU разный, ну и результаты тоже разные. См вложение - там все понятно.
Чтобы вернуть 223, то и в фильтре надо указывать [Время].[Месяц].[Предыдущий месяц]

Запрос для "велозавода" демонстрирует то же самое:

MDX для Adventure Works
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
WITH
SET [Анализируемый месяц] AS [Date].[Calendar Year].&[2006]
MEMBER [Date].[Calendar Year].[Базовый месяц] AS [Анализируемый месяц].Item(0)
MEMBER [Date].[Calendar Year].[Предыдущий месяц] AS [Анализируемый месяц].Item(0).Lag(1)	

MEMBER [Вычисляемая мера Предыдущий месяц Мера1] AS
	([Предыдущий месяц],[Measures].[Internet Sales Amount])	
		
MEMBER [Фильтр Предыдущий месяц Мера1] AS
	SUM(
		Filter(
			[Product].[Product].[Product],
			([Sales Territory].[Sales Territory Country].CurrentMember, [Measures].[Internet Sales Amount])<>0),
			([Предыдущий месяц], [Measures].[Internet Sales Amount]))
		
SELECT	
{   
   	{[Measures].[Internet Sales Amount], [Вычисляемая мера Предыдущий месяц Мера1], [Фильтр Предыдущий месяц Мера1]} *
	{[Предыдущий месяц], [Базовый месяц]}
}   ON 1,
NON EMPTY
	[Sales Territory].[Sales Territory Country].[Sales Territory Country]
	ON 0
FROM 
	(SELECT (
		[Date].[Calendar Year].&[2005]:[Date].[Calendar Year].&[2006],		
		[Sales Territory].[Sales Territory Country].&[Australia])
		On 0 FROM [Adventure Works]) 

...
Рейтинг: 0 / 0
Логика расчета
    #39438453
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ShIgorferzmikk,

Сейчас в фильтре участвует [Время].[Месяц].CurrentMember, и получается, что результирующий набор SKU разный, ну и результаты тоже разные. См вложение - там все понятно.
Чтобы вернуть 223, то и в фильтре надо указывать [Время].[Месяц].[Предыдущий месяц]
Получилось! Спасибо! Надо было написать так
Код: sql
1.
2.
3.
4.
5.
6.
MEMBER [Фильтр Предыдущий месяц Мера1] AS
	SUM(
		Filter(
			[SKU].[SKU].[SKU],
			([Торговые точки].[Код ТТ].CurrentMember, [Предыдущий месяц], [Measures].[Мера1])<>0),
		([Предыдущий месяц], [Measures].[Мера1]))
...
Рейтинг: 0 / 0
Логика расчета
    #39440513
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В общем, написал MDX-запрос для Adventure Works , который похож на реальный и упрощенный для быстрого понимания.

Задача такая. Выгружается поле [Internet Sales Amount] так, чтобы было скорректировано. Пример во вложенном файле. Там прописаны формулы и должно так считаться, предполагая что сейчас Апрель 2008. Логика такая что именно только для двух субкатегории ("Bike Stands" и "Bottles and Cages" ) для текущего (Апрель 2008) и предыдущего месяца (Март 2008) идет расчет от фактических данных, а ранее предыдущего месяца (Февраль 2008 и ранее) выгружаются фактические данные. Остальные субкатегории выгружаются по фактическим данным вне зависимо какой анализируемый месяц и какой сейчас месяц.

Запрос написал, запрос работает. Но получился очень сложный. Я думаю его можно написать попроще, учитывая что есть другие меры, которые надо также скорректировать. А также если написать в формуле проверку, чтобы знаменатель был не нулевым, то запрос удлиняется значительно.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
WITH
//Пусть сейчас апрель 2008 года, не важно какое число
MEMBER [Measures].[Текущий месяц] AS VBA!Format(VBA!Dateadd('m', 0, VBA!Dateserial(2008,04,01)), '01.MM.yyyy')
//Следовательно, предыдущий месяц это март 2008
MEMBER [Measures].[Предыдущий месяц] AS VBA!Format(VBA!DateAdd('m', -1, [Текущий месяц]), '01.MM.yyyy')

//В один сет толкаем один элемент Субкатегории
SET [Bike Stands] AS [Product].[Subcategory].&[27]
//В другой сет толкаем другой элемент Субкатегории
SET [Bottles and Cages] AS [Product].[Subcategory].&[28]

//Месяц и год для каждой строки
//Возможно эту меру написать попроще имея в Adventure Works специальные меры и атрибуты
MEMBER [Measures].[Соответствующий месяц] AS		
	VBA!Format(
		DATESERIAL(
			[Date].[Calendar Year].CURRENTMEMBER.MemberValue,
			[Date].[Month of Year].CURRENTMEMBER.MemberValue,
			1
		),
		 '01.MM.yyyy'
	)
	
//Скорректированная мера в зависимости от того какой анализируемый период берется и какой сейчас месяц
//Самое главное упростить надо тут
MEMBER [Measures].[Скоррект Internet Sales Amount] AS	
	(CASE WHEN ([Product].[Subcategory].CurrentMember IS [Bike Stands].Item(0)) OR 
		([Product].[Subcategory].CurrentMember IS [Bottles and Cages].Item(0)) THEN
		//Если месяц в строке это текущий месяц
		(CASE WHEN [Measures].[Соответствующий месяц] = [Текущий месяц] THEN
			([Date].[Calendar].CurrentMember.Lag(2),[Internet Sales Amount])
			/
			SUM(FILTER ({[Bike Stands],[Bottles and Cages]},
				([Customer].[City].CurrentMember,
					[Date].[Calendar].CurrentMember.Lag(2),
					[Measures].[Internet Sales Amount])>0),
			([Date].[Calendar].CurrentMember.Lag(2),[Internet Sales Amount]))
			*
			SUM(FILTER ({[Bike Stands],[Bottles and Cages]},
				([Customer].[City].CurrentMember,
					[Date].[Calendar].CurrentMember,
					[Measures].[Internet Sales Amount])>0),
			([Date].[Calendar].CurrentMember,[Internet Sales Amount])) 
		//Если месяц в строке это предыдущий от текущего месяца
		WHEN [Measures].[Соответствующий месяц] =[Предыдущий месяц] THEN
			([Date].[Calendar].CurrentMember.Lag(1),[Internet Sales Amount])
			/
			SUM(FILTER ({[Bike Stands],[Bottles and Cages]},
				([Customer].[City].CurrentMember,
					[Date].[Calendar].CurrentMember.Lag(1),
					[Measures].[Internet Sales Amount])>0),
			([Date].[Calendar].CurrentMember.Lag(1),[Internet Sales Amount]))
			*
			SUM(FILTER ({[Bike Stands],[Bottles and Cages]},
				([Customer].[City].CurrentMember,
					[Date].[Calendar].CurrentMember,
					[Measures].[Internet Sales Amount])>0),
			([Date].[Calendar].CurrentMember,[Internet Sales Amount]))
		//Если месяц в строке ранее предыдущего от текущего месяца
		WHEN [Measures].[Соответствующий месяц] <[Предыдущий месяц] THEN
			([Date].[Calendar].CurrentMember,[Internet Sales Amount]) 
		//Остальные месяцы (будущие)
		ELSE 
			NULL
		END)
        //Остальные субкатегории
        ELSE
              ([Date].[Calendar].CurrentMember,[Internet Sales Amount])
	END)
	
SELECT
	{[Measures].[Internet Sales Amount],
	[Measures].[Скоррект Internet Sales Amount]	}
ON 0,
	[Customer].[City].[City]*
	[Product].[Subcategory].[Subcategory]*
	[Date].[Calendar].[Month]*
	[Date].[Calendar Year].[Calendar Year]*
	[Date].[Month of Year].[Month of Year]
ON 1
FROM
	(SELECT ([Date].[Calendar].[Month].&[2008]&[1]:[Date].[Calendar].[Month].&[2008]&[11],
		[Customer].[City].&[Coffs Harbour]&[NSW],			
		{[Product].[Subcategory].&[27],	[Product].[Subcategory].&[28]}
		)	ON 0 FROM [Adventure Works])


Как можно его упростить? Есть то, что еще не учел? Или есть специальная функция? Или тут надо прописывать пользовательскую функцию с аргументами?
...
Рейтинг: 0 / 0
32 сообщений из 32, показаны все 2 страниц
Форумы / OLAP и DWH [игнор отключен] [закрыт для гостей] / Логика расчета
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]