Заменить selfjoin с аналитическими функциями - PullRequest
1 голос
/ 19 марта 2010

Как мне заменить следующее самоподключение с помощью аналитики:

SELECT 
t1.col1 col1,
t1.col2 col2,
SUM((extract(hour FROM (t1.times_stamp - t2.times_stamp)) * 3600 + extract(minute FROM ( t1.times_stamp - t2.times_stamp)) * 60 + extract(second FROM ( t1.times_stamp - t2.times_stamp)) ) ) div,
COUNT(*) tot_count
FROM tab1 t1,
tab1 t2
WHERE t2.col1      = t1.col1
AND t2.col2  = t1.col2
AND t2.col3        = t1.sequence_num
AND t2.times_stamp     < t1.times_stamp
AND t2.col4         = 3
AND t1.col4         = 4
AND t2.col5 NOT IN(103,123)
AND t1.col5     != 549
GROUP BY t1.col1, t1.col2

Ответы [ 2 ]

1 голос
/ 19 марта 2010

Я почти уверен, что вы не сможете заменить самостоятельное соединение аналитикой, потому что вы используете междурядные операции (t1.time_stamp - t2.time_stamp). Аналитика может получить доступ только к значениям текущей строки и значения агрегатных функций для подмножества строк (предложение windowing).

См. эту статью Тома Кайта и эту статью для дальнейшего анализа ограничений аналитики.

0 голосов
/ 23 декабря 2014

Это почти похоже, что вы можете исключить самостоятельное соединение на t2 и заменить

t1.time_stamp - t2.time_stamp

с чем-то вроде

t1.time_stamp - lag(t1.time_stamp) over (partition by col1, col2 order by time_stamp)

Различные фильтры на t1 и t2 на col4 и col5 - вот что мешает вам сделать это.
Аналитические функции применяются после где / сгруппировать в основном запросе, поэтому вам нужно иметь один фильтр для t1, чтобы использовать lag / lead для указания следующих или предшествующих строк в последовательности.

Кроме того, вам нужно отправить сумму / группу во внешний запрос для агрегирования после аналитической функции:

select col1, col2, sum(timestamp_diff) from (
  select col1, col2, timestamp - lag(timestamp) over(.....) as timestamp_diff
  where ....
) group by col1, col2
...