2015-01-15 3 views
2

У меня есть запрос CONNECT BY, из которого я не получаю желаемых результатов.Не получения полного умножения (продукта) в запросе CONNECT-BY

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

Он начинается с таблицы с сохраненными процентами (РСТ) из года в год. По мере продвижения запроса он должен принять PCT с первого года и умножить его на PCT со следующего года и так далее, пока не достигнет желаемой глубины. Предполагается, что эффект подобен умножению по диагонали на кросс-вкладку, где YR (год) и yset представляют начальную строку и столбец.

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

Это может быть простая ошибка, но дополнительные глаза помогут быстрее разобраться.

Код:

 with recurreten as 
(
select YR, YSet, 
     rtnpct rtn_year, 
     level lvl, ' - ' s1, 
     rtnpct * nvl(prior rtnpct, 1) rtnpct 
     --- Below here only for checking the paths 
     , sys_connect_by_path(nvl(rtnpct, 1) , '/') prodpath 
from Z_RETENTIONPCT 
    connect by yr = prior yr+1 and yset = prior yset+1 
    start with YR = 1998 -- :StartYr 
       and 
       yset = 20 -- :StartYSet 
) 

-- final results 
select yr, yset, 
     round(rtn_year * 100, 2) rtn_year, 
     lvl, -- years the Cumulative Continuation Rate is extended 
     s1, 
     round(rtnpct, 2) CCR 
     --- Below here only for checking results 
     , rtnpct CCRFull -- Extra digits, for math check 
     , prodpath -- Only used by us, to check the #'s feeding the CCR 
from recurreten 
where lvl <= 10 -- :Depth  
order by yr, yset, lvl 
; 

Я настроил пример в SQLFiddle на http://sqlfiddle.com/#!4/ce945/1/0
В примере используется СО установить некоторые фиктивные данные.

Результаты примеры были бы: (желаемые результаты)

Year Col  Reten_yr Full prod Full Prod Path 
1998 20  0.84766  0.847660000 = 0.84766 
1999 21  0.77941  0.660674681 = 0.84766 * 0.77941 
2000 22  0.78659  0.519680097 = 0.84766 * 0.77941 * 0.78659 
2001 23  0.76879  0.399524862 = 0.84766 * 0.77941 * 0.78659 * 0.76879 

(текущие/неправильные результаты)

Year Col  Reten_yr wrong prod Partial Path 
1998 20  0.84766  0.847660000 = 0.84766 
1999 21  0.77941  0.660674681 = 0.84766 * 0.77941 
2000 22  0.78659  0.613076112 =   0.77941 * 0.78659 
2001 23  0.76879  0.604722526 =      0.78659 * 0.76879 

Почему я не получаю полный (умножение) продукт? Что я могу сделать, чтобы исправить это? Кто угодно...? Кто угодно? Bueller?

ОБНОВЛЕНИЕ: Ешьте Персик, обеспечивающий исправление, необходимое для получения действительно кумулятивных результатов. Мне пришлось обновить этот пример из-за того, что я вручную подбирал образцы данных, которые спрятали объем регулярных данных: строки на 50+ лет последовательно, до 70 YCS за каждый год. В обновленном запросе выполнялись последовательные кумулятивные продукты, и мое требование - «диагонально последовательные кумулятивные продукты». Я сохранил решение для добавления журнала и добавил CONNECT BY обратно.

http://sqlfiddle.com/#!4/1c326/2

Показывает некоторые значения по умолчанию для начальных точек и глубину.

Еще раз спасибо!

ответ

4

Что вам нужно - это кумулятивное умножение. Но нет такой функции, как Агрегатная или Аналитическая функция. Но математика говорит нам умножение. можно изменить на addition using logarithm.

a * b = exp(ln(a) + ln(b)) 

Используйте это в SUM в качестве аналитической функции. Не нужно использовать конструкцию CONNECT BY.

SQL Fiddle

recurreten as 
(
select YR, YSet, 
     rtnpct rtn_year, 
     round(exp(sum(ln(rtnpct)) over (order by yr, yset rows between unbounded preceding and current row)),2) ccr, 
     exp(sum(ln(rtnpct)) over (order by yr, yset rows between unbounded preceding and current row)) ccrfull 
from Z_RETENTIONPCT 
) 
select * from recurreten 
order by yr, yset 

Results:

| YR | YSET | RTN_YEAR | CCR |  CCRFULL | 
|------|------|----------|------|----------------| 
| 1998 | 20 | 0.84766 | 0.85 |  0.84766 | 
| 1999 | 21 | 0.77941 | 0.66 | 0.6606746806 | 
| 2000 | 22 | 0.78659 | 0.52 | 0.519680097013 | 
| 2001 | 23 | 0.76879 | 0.4 | 0.399524861783 | 
| 2002 | 24 | 0.80952 | 0.32 | 0.32342336611 | 
| 2003 | 25 | 0.76316 | 0.25 | 0.246823776081 | 
| 2004 | 26 | 0.82425 | 0.2 | 0.203444497435 | 
| 2005 | 27 | 0.6992 | 0.14 | 0.142248392606 | 
| 2006 | 28 | 0.77071 | 0.11 | 0.109632258666 | 
| 2007 | 29 | 0.702 | 0.08 | 0.076961845583 | 
+0

Что удивительным и элегантное решение. Я беру это на главный сервер, и я попробую его по реальным данным ... Я очень надеюсь на это решение! – Marc

+0

Обновление: @EAP - ТАК ЗАКРЫТЬ! Он не справился с реальными данными, потому что я вручную подбирал образцы данных. Фактическая таблица состоит из, возможно, 70 последовательных строк «yset» для каждого года, затем следующего года и т. Д. Qry должен быть «диагонально кумулятивным», а не серийно кумулятивным. Добавление Connect By назад позволило мне автоматически выполнять «следующий год/следующий YCS». Я также добавил некоторые пользовательские переменные, чтобы разрешить мне начинать с указанного смещения и ограничивать, насколько это необходимо, в серии. Но все же, потрясающее и элегантное решение! Я обновлю вопрос для иллюстрации. – Marc