Предложение Rexem об использовании LAG () является правильным подходом, но нам нужно использовать условие разделения. Это становится понятным, как только мы добавим строки для разных интервалов и разных станций ...
SQL> select * from t
2 /
STATIONID FORECASTDATE INTERVAL FORECASTCREATED FORECASTVALUE
---------- ------------ -------- ------------------- -------------
stationa 13-12-2009 10 10-12-2009 04:50:10 0
stationa 13-12-2009 10 10-12-2009 17:06:13 0
stationa 13-12-2009 10 12-12-2009 05:20:50 300
stationa 13-12-2009 10 13-12-2009 09:20:50 300
stationa 13-12-2009 11 13-12-2009 09:20:50 400
stationb 13-12-2009 11 13-12-2009 09:20:50 500
6 rows selected.
SQL> SELECT v.stationid,
2 v.forecastcreated,
3 v.forecastvalue,
4 (v.forecastdate + v.forecastinterval / 24) fcst_date
5 FROM (SELECT t.stationid,
6 t.forecastdate,
7 t.forecastinterval,
8 t.forecastcreated,
9 t.forecastvalue,
10 t.forecastvalue - LAG(t.forecastvalue, 1)
11 OVER (ORDER BY t.forecastcreated) as difference
12 FROM t) v
13 WHERE v.difference >= 100
14 /
STATIONID FORECASTCREATED FORECASTVALUE FCST_DATE
---------- ------------------- ------------- -------------------
stationa 12-12-2009 05:20:50 300 13-12-2009 10:00:00
stationa 13-12-2009 09:20:50 400 13-12-2009 11:00:00
stationb 13-12-2009 09:20:50 500 13-12-2009 11:00:00
SQL>
Чтобы удалить ложные срабатывания, мы группируем LAG () по STATIONID, FORECASTDATE и FORECASTINTERVAL. Обратите внимание, что следующее опирается на внутренний запрос, возвращающий NULL из первого вычисления каждого окна раздела.
SQL> SELECT v.stationid,
2 v.forecastcreated,
3 v.forecastvalue,
4 (v.forecastdate + v.forecastinterval / 24) fcst_date
5 FROM (SELECT t.stationid,
6 t.forecastdate,
7 t.forecastinterval,
8 t.forecastcreated,
9 t.forecastvalue,
10 t.forecastvalue - LAG(t.forecastvalue, 1)
11 OVER (PARTITION BY t.stationid
12 , t.forecastdate
13 , t.forecastinterval
14 ORDER BY t.forecastcreated) as difference
15 FROM t) v
16 WHERE v.difference >= 100
17 /
STATIONID FORECASTCREATED FORECASTVALUE FCST_DATE
---------- ------------------- ------------- -------------------
stationa 12-12-2009 05:20:50 300 13-12-2009 10:00:00
SQL>
Работа с большими объемами данных
Вы описываете свои таблицы как содержащие много сотен миллионов строк. Такие огромные столы похожи на черные дыры, у них другая физика. Существуют различные потенциальные подходы, в зависимости от ваших потребностей, сроков, финансов, версии и редакции базы данных, а также любого другого использования данных вашей системы. Это более пятиминутный ответ.
Но все равно вот пятиминутный ответ.
Предполагая, что ваша таблица является живой таблицей, она, вероятно, заполняется, добавляя прогнозы по мере их появления, что по сути является дополнительной операцией. Это будет означать, что прогнозы для любой данной станции разбросаны по всей таблице. Следовательно, индексы только STATIONID или даже FORECASTDATE будут иметь плохой фактор кластеризации.
Исходя из этого, я рекомендую вам сначала попробовать создать индекс на (STATIONID, FORCASTDATE, FORECASTINTERVAL, FORECASTCREATED, FORECASTVALUE)
. Это займет некоторое время (и дисковое пространство) для сборки, но это должно значительно ускорить ваши последующие запросы, поскольку в нем есть все столбцы, необходимые для удовлетворения запроса с помощью INDEX RANGE SCAN, не касаясь таблицы вообще.