SQL.RU
 client/server technologies
 
 Главная | Документация | Статьи | Книги | Форум | Опросы | Рассылка | Работа | Поиск | FAQ |

Добро пожаловать в форум, Guest  >>  Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / OLAP и DWH Новый топик  Ответить
 Рекурсия и Running Total (применительно к ABC Analysis)   [new]
Владимир Штепа
Member

Откуда: Hannover
Сообщений: 5676
Дискуссия на эту тему возникла спонтанно в другом топике.
Я вынес это в отдельную тему

backfire
Mosha
Замечу что в Юконе, Ваше выражение сработает без проблем, потому что умный Юкон умеет сам разобраться что делать с бесконечной рекурсией - он просто разобьет цикл сам понизив pass.
Вот пример похожей задачи сделанной на Юконе:
http://www.sqlserveranalysisservices.com/OLAPPapers/Loading%20Aggregate%20Data%20in%20AS2005v2.htm

Моша
----------------------------------------------------
This posting is provided "AS IS" with no warranties, and confers no rights


Коль пошла речь о рекурсии, то можно ли еще в AS2K в следующем запросе
Избежать ненужных вычислений, переписав формулу для RunningTotal чтобы AS считал a la Excel, a не a la SQL.

WITH 

-- Runnig Total
member [Time].[Column 2] as '
SUM(HEAD([TotalSet],RANK([Customers].CURRENTMEMBER,[TotalSet])),
        ([Time].[1998],[Measures].CURRENTMEMBER))'

SET [RowSet0] AS '{[Customers].[City].members}'
-- Sort 
SET [RowSet2] AS 'topcount([RowSet0],100,([Time].[1998], [Measures].[Store Sales]))'
SET [TotalSet] AS '[RowSet2]'

member [Customers].[TotalMember] AS '[Customers].[All Customers]'
SELECT
{[Time].[1998],[Time].[Column 2]} ON COLUMNS,
 CROSSJOIN({[RowSet2]},{[Measures].[Store Sales]})

ON ROWS
FROM Sales

то есть, как переписать формулу

member [Time].[Column 2] as '
SUM(HEAD([TotalSet],RANK([Customers].CURRENTMEMBER,[TotalSet])),
        ([Time].[1998],[Measures].CURRENTMEMBER))'

к виду (

member [Time].[Column 2] as '([Time].[1998],[Measures].CURRENTMEMBER) + 
Предыдущий([Time].[Column 2])'

Возможно ли тут каким либо образом, притянув CalculationPass решить проблему.

Проблема в том что потребное время для выполнения

member [Time].[Column 2] as '
SUM(HEAD([TotalSet],RANK([Customers].CURRENTMEMBER,[TotalSet])),
        ([Time].[1998],[Measures].CURRENTMEMBER))'

пропорционально квадрату количества мемберов в [TotalSet]


Mosha
Да, конечно можно - это стандартная задача, и можно применить рекурсию. Посколько рекурсия в этом случае не бесконечная, то у AS2K нет с этим никаких проблем и CalculationPassValue не нужен.

Моша
----------------------------------------------------
This posting is provided "AS IS" with no warranties, and confers no rights


backfire
Mosha
Да, конечно можно - это стандартная задача, и можно применить рекурсию. Посколько рекурсия в этом случае не бесконечная, то у AS2K нет с этим никаких проблем и CalculationPassValue не нужен.

Моша
----------------------------------------------------
This posting is provided "AS IS" with no warranties, and confers no rights


Если это стандартная задача, то об этом должно быть где то написано, примеры приведены. Но я почему то невстречал :-(

Ну а у меня вот что наваялось.

WITH 

-- Runnig Total
-- a)
member [Time].[Column 2] as '
SUM(HEAD([TotalSet],RANK([Customers].CURRENTMEMBER,[TotalSet])),
        ([Time].[1998],[Measures].CURRENTMEMBER))'

-- b)
member [Time].[Column 3] as '([Time].[1998],[Measures].CURRENTMEMBER,[Customers].CURRENTMEMBER) +
 Iif(RANK([Customers].CURRENTMEMBER,[TotalSet])=1,null,
([Time].[Column 3],[Measures].CURRENTMEMBER,[TotalSet].Item(RANK([Customers].CURRENTMEMBER,[TotalSet])-2)))'

-- c)
member [Time].[Column 4] as '([Time].[1998],[Customers].CURRENTMEMBER) +
 Iif(RANK([Customers].CURRENTMEMBER,[TotalSet])=1,null,
([Time].[Column 4],[TotalSet].Item(RANK([Customers].CURRENTMEMBER,[TotalSet])-2)))'


SET [RowSet0] AS '{[Customers].[Name].Members}'
-- Sort 
SET [RowSet2] AS 'topcount([RowSet0],1000,([Time].[1998], [Measures].[Store Sales]))'
SET [TotalSet] AS '[RowSet2]'

member [Customers].[TotalMember] AS '[Customers].[All Customers]'
SELECT
{[Time].[1998],[Time].[Column 2], [Time].[Column 3], [Time].[Column 4]} ON COLUMNS,
 CROSSJOIN({[RowSet2]},{[Measures].[Store Sales]})

ON ROWS
FROM Sales

эффект от вариантов в) и с) как и ожидалось, рассчитывается гораздо быстрее чем а)

Принципиально ли различие в написании в) и с)? Можно ли обойтись без использования RANK? Оно конечно не мешает, но выглядит как то коряво...
Не покажете ли более "красивый" вариант, если он существует.


Mosha
В Вашем примере running sum по customers это для примера или действительно надо. Как то обычно running sum делают по времени. А вообще-то конечно у Вас все очень переусложнено, можно сделать гораздо проще и никаких Rank не нужно. Хотя с другой стороны, Вы не сформулиров задачи сразу стали приводить варианты решения, поэтому я не уверен чего именно Вы хотите добиться. И еще, навеное это надо бы в другой thread, а то Дмитрий обидится - влезли мы в его дискуссию и обсуждаем вещи никак не связанные с его вопросом...

Моша
----------------------------------------------------
This posting is provided "AS IS" with no warranties, and confers no rights
23 янв 05, 16:29    [1267048] Ответить | Цитировать    Сообщить модератору

 Re: Рекурсия и Running Total (применительно к ABC Analysis)   [new]
Владимир Штепа
Member

Откуда: Hannover
Сообщений: 5676
Mosha
В Вашем примере running sum по customers это для примера или действительно надо. Как то обычно running sum делают по времени. А вообще-то конечно у Вас все очень переусложнено, можно сделать гораздо проще и никаких Rank не нужно. Хотя с другой стороны, Вы не сформулиров задачи сразу стали приводить варианты решения, поэтому я не уверен чего именно Вы хотите добиться. И еще, навеное это надо бы в другой thread, а то Дмитрий обидится - влезли мы в его дискуссию и обсуждаем вещи никак не связанные с его вопросом...

Моша
----------------------------------------------------
This posting is provided "AS IS" with no warranties, and confers no rights


Running Sum не по времени, а по отсортированному сет из другого измерения (Customrs, Product etc.) действительно надо. Это лежит в основе Парето/ABC-анализа. А подход с

SUM(HEAD([TotalSet],RANK([Customers].CURRENTMEMBER,[TotalSet])),
        ([Time].[1998],[Measures].CURRENTMEMBER))

я подглядел у Споффорда, где он как раз предлагает подобную формулу для Парето/ABC анализа.

Теперь вы знаете для чего это и зачем. Является ли предложенный мною подход все еще переусложненным?
23 янв 05, 16:30    [1267049] Ответить | Цитировать    Сообщить модератору

 Re: Рекурсия и Running Total (применительно к ABC Analysis)   [new]
Владимир Штепа
Member

Откуда: Hannover
Сообщений: 5676
Mosha
А вообще-то конечно у Вас все очень переусложнено, можно сделать гораздо проще и никаких Rank не нужно. Хотя с другой стороны, Вы не сформулиров задачи сразу стали приводить варианты решения, поэтому я не уверен чего именно Вы хотите добиться.


Привожу пример запроса. Нужен он для ABC анализов.

WITH 

-- % to Total
member [Time].[% to Total] as '
([Time].[1998], [Product].CURRENTMEMBER,[Measures].CURRENTMEMBER)*100.0 / 
([Time].[1998], [Product].[TotalMember],[Measures].CURRENTMEMBER)', SOLVE_ORDER=1

-- Runnig Total
member [Time].[Runnig Total] as '([Time].[1998],[Measures].CURRENTMEMBER,[Product].CURRENTMEMBER) +
 Iif(RANK([Product].CURRENTMEMBER,[TotalSet])=1,null,
([Time].[Runnig Total],[Measures].CURRENTMEMBER,[TotalSet].Item(RANK([Product].CURRENTMEMBER,[TotalSet])-2)))', SOLVE_ORDER=1

-- Runnig Total % Ratio
member [Time].[Runnig Total %] as '([Time].[1998],[Measures].CURRENTMEMBER,
[Product].CURRENTMEMBER) *100/([Time].[1998],[Measures].CURRENTMEMBER,[Product].[TotalMember]) +
 Iif(RANK([Product].CURRENTMEMBER,[TotalSet])=1,null,
([Time].[Runnig Total %],[Measures].CURRENTMEMBER,[TotalSet].Item(RANK([Product].CURRENTMEMBER,[TotalSet])-2)))', SOLVE_ORDER=1




SET [RowSet0] AS '[Product].[Product Category].members'
-- Sort 
SET [RowSet2] AS 'topcount([RowSet0],1000,([Time].[1998], [Measures].[Store Sales]))'
SET [TotalSet] AS '[RowSet2]'

member [Product].[TotalMember] AS '[Product].[All Products]'
SELECT
CROSSJOIN({[Time].[1998],  [Time].[% to Total], [Time].[Runnig Total], [Time].[Runnig Total %]},
{[Measures].[Store Sales], [Measures].[Unit Sales]}) ON COLUMNS,

{[Product].[All Products], [RowSet2]}

ON ROWS
FROM Sales

На какой оси показывать меры - вопрос третичный.
24 янв 05, 01:28    [1267410] Ответить | Цитировать    Сообщить модератору

 Re: Рекурсия и Running Total (применительно к ABC Analysis)   [new]
Mosha
Member

Откуда:
Сообщений: 1270
Если set может быть произвольным, и отсортирован по произвольному признаку, то тогда я вообще затрудняюсь с вариантом решения. Rank не сработает как Вам хочется когда в set есть дупликаты. Споффорд эту проблему обходит гарантируя что в его set дупликатов нет. Видимо в Ваших примерах их тоже никогда не будет. Но все равно все 3 варианта выглядят довольно некрасиво. Идеальным решением было бы использовать CurrentOrdinal на алиасе, но в оффициальном MDX такого метода до сих пор нет. Так что я не знаю как решить эту задачу в общем случае.
Возвращаясь ка началу темы - удтверждение, что рекурсия будет всегда быстрее чем суммирование. Тоже самое говорит и Споффорд, но тут есть о чем поспорить. Рекурсия для производительности - это обычно плохо, поскольку query optimizer на ней как правило сдается. Единственное что вытягивает примеры b и c так это formula cache, т.к. значения partial sums посчитанные на предыдущих tuples уже закешированы. Но это довольно слабая гарантия. Приготовтесь к тому, что с выходом Юкона, где query optimizer будет посильнее чем у AS2K, performance profile у подобных запросов сильно изменится и не в пользу рекурсии...

Моша
----------------------------------------------------
This posting is provided "AS IS" with no warranties, and confers no rights
24 янв 05, 02:10    [1267420] Ответить | Цитировать    Сообщить модератору

 Re: Рекурсия и Running Total (применительно к ABC Analysis)   [new]
Владимир Штепа
Member

Откуда: Hannover
Сообщений: 5676
Mosha
Если set может быть произвольным, и отсортирован по произвольному признаку, то тогда я вообще затрудняюсь с вариантом решения. Rank не сработает как Вам хочется когда в set есть дупликаты. Споффорд эту проблему обходит гарантируя что в его set дупликатов нет. Видимо в Ваших примерах их тоже никогда не будет.

Да, сет у меня может быть произвольным, но гарантировано без дубликатов.
А у Споффорда я не нашел рекурсии только с SUM.


Mosha
Но все равно все 3 варианта выглядят довольно некрасиво. Идеальным решением было бы использовать CurrentOrdinal на алиасе, но в оффициальном MDX такого метода до сих пор нет. Так что я не знаю как решить эту задачу в общем случае.

Что же тогда еще (добавить, изменить, удалить) в моих формулах, чтобы они стали изящными, но без потери эффективности. Что за CurrentOrdinal вы упоминаете?
Что вы подрозумеваете под общим случаем? Создать CМ и засунуть его в куб?

Mosha
Возвращаясь ка началу темы - удтверждение, что рекурсия будет всегда быстрее чем суммирование. Тоже самое говорит и Споффорд, но тут есть о чем поспорить. Рекурсия для производительности - это обычно плохо, поскольку query optimizer на ней как правило сдается. Единственное что вытягивает примеры b и c так это formula cache, т.к. значения partial sums посчитанные на предыдущих tuples уже закешированы. Но это довольно слабая гарантия. Приготовтесь к тому, что с выходом Юкона, где query optimizer будет посильнее чем у AS2K, performance profile у подобных запросов сильно изменится и не в пользу рекурсии...


Нельзя ли подробнее про формула formula cache и partial sums. Или где про это прочитать?
Ну а про информацию о query optimizer в Юкона я только мечтать могу.
24 янв 05, 11:15    [1267965] Ответить | Цитировать    Сообщить модератору

 Re: Рекурсия и Running Total (применительно к ABC Analysis)   [new]
Mosha
Member

Откуда:
Сообщений: 1270
Я продолжу обсуждение этой проблемы попозже. Сегодня утром я привел этот thread как пример на triage. И хотя почти половина людей по русски у нас не понимает, но приведенный MDX сам за себя говорит и проблема ясна. Так что будем ждать что произойдет дальше.

Моша
----------------------------------------------------
This posting is provided "AS IS" with no warranties, and confers no rights
24 янв 05, 23:41    [1270275] Ответить | Цитировать    Сообщить модератору

 Re: Рекурсия и Running Total (применительно к ABC Analysis)   [new]
Владимир Штепа
Member

Откуда: Hannover
Сообщений: 5676
Mosha
Я продолжу обсуждение этой проблемы попозже. Сегодня утром я привел этот thread как пример на triage. И хотя почти половина людей по русски у нас не понимает, но приведенный MDX сам за себя говорит и проблема ясна. Так что будем ждать что произойдет дальше.

Моша
----------------------------------------------------
This posting is provided "AS IS" with no warranties, and confers no rights


Моша, если вы мене растолкуете, шо такое "triage", то его публика будет через пол часа читать по англицки, какие проблемы. :-)
25 янв 05, 00:09    [1270312] Ответить | Цитировать    Сообщить модератору

 Re: Рекурсия и Running Total (применительно к ABC Analysis)   [new]
Mosha
Member

Откуда:
Сообщений: 1270
Triage - это такая комиссия (в основном начальников), которые решают что чинить, а что не чинить в продукте. Поскольку Юкон подходит к концу, то практически все нетривиальные проблемы должны через эту коммисию проходить. Английский перевод не нужен - они уже поняли в чем дело...

Моша
----------------------------------------------------
This posting is provided "AS IS" with no warranties, and confers no rights
25 янв 05, 00:19    [1270324] Ответить | Цитировать    Сообщить модератору

 Re: Рекурсия и Running Total (применительно к ABC Analysis)   [new]
Владимир Штепа
Member

Откуда: Hannover
Сообщений: 5676
Mosha
Triage - это такая комиссия (в основном начальников), которые решают что чинить, а что не чинить в продукте. Поскольку Юкон подходит к концу, то практически все нетривиальные проблемы должны через эту коммисию проходить. Английский перевод не нужен - они уже поняли в чем дело...

Моша
----------------------------------------------------
This posting is provided "AS IS" with no warranties, and confers no rights


Неужели мои мелкие проблемы сподивигают кого то что то чинить в Юконе?
25 янв 05, 00:28    [1270335] Ответить | Цитировать    Сообщить модератору

 Re: Рекурсия и Running Total (применительно к ABC Analysis)   [new]
Владимир Штепа
Member

Откуда: Hannover
Сообщений: 5676
Mosha
И хотя почти половина людей по русски у нас не понимает


Это сильно сказано!!!

Пока, не понимает :-)
25 янв 05, 00:32    [1270337] Ответить | Цитировать    Сообщить модератору

 Re: Рекурсия и Running Total (применительно к ABC Analysis)   [new]
Владимир Штепа
Member

Откуда: Hannover
Сообщений: 5676
Mosha
Но все равно все 3 варианта выглядят довольно некрасиво.


Методом "научного тыка" (... и опыт - сын ошибок трудных...) я установил, что немного красоты можно добавить, избавившись от жалкого наследия VBA в лице IIF. В этом случае все выглядет гораздо изящнее.

WITH 
-- % to Total
member [Time].[% of Total] as '
([Time].[1998], [Product].CURRENTMEMBER,[Measures].CURRENTMEMBER)*100.0 /
([Time].[1998], [Product].[TotalMember],[Measures].CURRENTMEMBER)', SOLVE_ORDER=1
-- Runnig Total
member [Time].[Runnig Total] as '([Time].[1998],[Product].CURRENTMEMBER) +
([Time].[Runnig Total],[TotalSet].Item(RANK([Product].CURRENTMEMBER,[TotalSet])-2))'
, SOLVE_ORDER=1
-- Runnig Total % Ratio
member [Time].[Runnig Total %] as '([Time].[1998],[Product].CURRENTMEMBER) *100/([Time].[1998],[Product].[TotalMember]) +
([Time].[Runnig Total %],[TotalSet].Item(RANK([Product].CURRENTMEMBER,[TotalSet])-2))'
, SOLVE_ORDER=1

SET [RowSet0] AS '[Product].[Product Category].members'
-- Sort 
SET [RowSet2] AS 'topcount([RowSet0],1000,([Time].[1998], [Measures].[Store Sales]))'
SET [TotalSet] AS '[RowSet2]'

member [Product].[TotalMember] AS '[Product].[All Products]'
SELECT
CROSSJOIN({[Measures].[Store Sales], [Measures].[Unit Sales]}, 
{[Time].[1998],  [Time].[Runnig Total], [Time].[% of Total], [Time].[Runnig Total %]}
) ON COLUMNS,

{[Product].[All Products], [RowSet2]} ON ROWS
FROM Sales

Но тут возникает следующий вопрос.
Почему <<Set>>.Item(-1) не выбрасывает "Index out of range"???
Можно придумать 1000 ситуаций, где такое "замалчивание грехов" будет иметь пагубное влияние.
26 янв 05, 03:53    [1273440] Ответить | Цитировать    Сообщить модератору

 Re: Рекурсия и Running Total (применительно к ABC Analysis)   [new]
Mosha
Member

Откуда:
Сообщений: 1270
Mosha
Я продолжу обсуждение этой проблемы попозже

Итак наступило "попозже", т.е. вышел февральский CTP. Уважаемый backfire, я думаю что Вы будете рады узнать, что в этом CTP мы добавили функцию CurrentOrdinal в MDX. Ваш сценарий сыграл в этом решающую роль :)

Моша
----------------------------------------------------
This posting is provided "AS IS" with no warranties, and confers no rights
4 мар 05, 20:46    [1365349] Ответить | Цитировать    Сообщить модератору

 Re: Рекурсия и Running Total (применительно к ABC Analysis)   [new]
Владимир Штепа
Member

Откуда: Hannover
Сообщений: 5676
Mosha
Mosha
Я продолжу обсуждение этой проблемы попозже

Итак наступило "попозже", т.е. вышел февральский CTP. Уважаемый backfire, я думаю что Вы будете рады узнать, что в этом CTP мы добавили функцию CurrentOrdinal в MDX. Ваш сценарий сыграл в этом решающую роль :)

Моша
----------------------------------------------------
This posting is provided "AS IS" with no warranties, and confers no rights


Приятно слышать.

А в BOL отобразили рекомендации к употреблению? А то релиз ноутс в части AS выглядит как-будто бы его писали за 2 минуты в конце рабочего дня пятницы.
5 мар 05, 00:46    [1365597] Ответить | Цитировать    Сообщить модератору

Все форумы / OLAP и DWH Ответить
Generated time: 171ms.
Rambler's Top100 Powered by ActualForum 1.5.3 [s1] Copyright (c) Alex Sibilev 2000-2010