Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 вывод статистических данных срезов с интерполяцией  [new]
kgtu
Member

Откуда:
Сообщений: 4
Прошу помощи с запросом

Есть таблица со срезами текущего значения какого-либо параметра в момент времени, для примера заполнил температурой.
Нужно получить значения для произвольных дат, то есть интерполировать.
то есть например в 01.06.2013 09:00:00 это будет 15 (интерполяция между ближайшими значениями 6 и 12 часов), в 01.06.2013 12:00:00 это будет 20 (точное совпадение даты).

Это необходимо для получения таблицы вида дата - значение параметра 1 - значение параметра 2 - ...
Данные в таблицу пишутся не в конкретный момент времени, а разрозненно, а нужно в итоге сгруппировать по дате

with t as(
select 1 id, to_date('01.06.2013 00:00:00', 'dd.mm.yyyy hh24:mi:ss') dt, 3 val from dual
union all
select 1, to_date('01.06.2013 06:00:00', 'dd.mm.yyyy hh24:mi:ss'), 10 from dual
union all
select 1, to_date('01.06.2013 12:00:00', 'dd.mm.yyyy hh24:mi:ss'), 20 from dual
union all
select 1, to_date('01.06.2013 18:00:00', 'dd.mm.yyyy hh24:mi:ss'), 18 from dual
)
select * from t
order by dt,id


В итоге при запросе например between to_date('01.06.2013 06:00:00', 'dd.mm.yyyy hh24:mi:ss') and to_date('01.06.2013 13:00:00', 'dd.mm.yyyy hh24:mi:ss') с заданным шагом, например 1 час будет нечто типа

with t as(
select 1 id, to_date('01.06.2013 06:00:00', 'dd.mm.yyyy hh24:mi:ss') dt, 10 val from dual
union all
select 1, to_date('01.06.2013 07:00:00', 'dd.mm.yyyy hh24:mi:ss'), 10+10/6 from dual
union all
select 1, to_date('01.06.2013 08:00:00', 'dd.mm.yyyy hh24:mi:ss'), 10+10/6*2 from dual
union all
select 1, to_date('01.06.2013 09:00:00', 'dd.mm.yyyy hh24:mi:ss'), 10+10/6*3 from dual
union all
select 1, to_date('01.06.2013 10:00:00', 'dd.mm.yyyy hh24:mi:ss'), 10+10/6*4 from dual
union all
select 1, to_date('01.06.2013 11:00:00', 'dd.mm.yyyy hh24:mi:ss'), 10+10/6*5 from dual
union all
select 1, to_date('01.06.2013 12:00:00', 'dd.mm.yyyy hh24:mi:ss'), 20 from dual
union all
select 1, to_date('01.06.2013 12:00:00', 'dd.mm.yyyy hh24:mi:ss'), 20-2/6 from dual
)
select * from t
order by dt,id
10 июн 13, 13:42    [14414786]     Ответить | Цитировать Сообщить модератору
 Re: вывод статистических данных срезов с интерполяцией  [new]
varlamovvp
Member

Откуда: Moscow
Сообщений: 297
Доброго дня!

with t as(
select 1 id, to_date('01.06.2013 00:00:00', 'dd.mm.yyyy hh24:mi:ss') dt, 3 val from dual
union all
select 1, to_date('01.06.2013 06:00:00', 'dd.mm.yyyy hh24:mi:ss'), 10 from dual
union all
select 1, to_date('01.06.2013 12:00:00', 'dd.mm.yyyy hh24:mi:ss'), 20 from dual
union all
select 1, to_date('01.06.2013 18:00:00', 'dd.mm.yyyy hh24:mi:ss'), 18 from dual
),
dan as( select to_date('01.06.2013 13:00:00', 'dd.mm.yyyy hh24:mi:ss') as d from dual)
select
case when t2-t1=0
then t1
else (t0-t1)/(t2-t1)*(v2-v1)+v1
end as v0
from
(
select
(select max(val) keep (dense_rank last order by dt) from t,dan where t.dt<=dan.d) as v1,
(select max(dt) from t,dan where t.dt<=dan.d) as t1,
(select min(val) keep (dense_rank last order by dt) from t,dan where t.dt>=dan.d) as v2,
(select min(dt) from t,dan where t.dt>=dan.d) as t2,
(select dan.d from dan) as t0
from dual
)


Только прошу прощения, надо определить "операцию вычитания дат". Я этого не сделал.
В смысле, если даты поменять просто на числа, все будет работать.
Ограничения : экстраполяция не сработает
Данные я ввел запросом DAN
10 июн 13, 15:17    [14415616]     Ответить | Цитировать Сообщить модератору
 Re: вывод статистических данных срезов с интерполяцией  [new]
SQL*Plus
Member

Откуда: Россия, Москва
Сообщений: 8131
varlamovvp
Доброго дня!
with t as(
select 1 id, to_date('01.06.2013 00:00:00', 'dd.mm.yyyy hh24:mi:ss') dt, 3 val from dual
union all
select 1, to_date('01.06.2013 06:00:00', 'dd.mm.yyyy hh24:mi:ss'), 10 from dual
union all
select 1, to_date('01.06.2013 12:00:00', 'dd.mm.yyyy hh24:mi:ss'), 20 from dual
union all
select 1, to_date('01.06.2013 18:00:00', 'dd.mm.yyyy hh24:mi:ss'), 18 from dual
),
  dan as( select to_date('01.06.2013 13:00:00', 'dd.mm.yyyy hh24:mi:ss') as d from dual)
select
  case when t2-t1=0 
      then t1
      else (t0-t1)/(t2-t1)*(v2-v1)+v1
   end as v0
from 
(
select 
  (select max(val) keep (dense_rank last order by dt) from t,dan where t.dt<=dan.d) as v1,
  (select max(dt) from t,dan where t.dt<=dan.d) as t1,
  (select min(val) keep (dense_rank last order by dt) from t,dan where t.dt>=dan.d) as v2,
  (select min(dt) from t,dan where t.dt>=dan.d) as t2,
  (select dan.d from dan) as t0
from dual
)

Только прошу прощения, надо определить "операцию вычитания дат". Я этого не сделал.
В смысле, если даты поменять просто на числа, все будет работать.
Ограничения : экстраполяция не сработает
Данные я ввел запросом DAN
Для оформления кода используйте, пожалуйста тэг SRC данного форума.
10 июн 13, 19:26    [14417344]     Ответить | Цитировать Сообщить модератору
 Re: вывод статистических данных срезов с интерполяцией  [new]
Batsall
Member

Откуда: Москва
Сообщений: 360
kgtu,

with t as(
select 1 id, to_date('01.06.2013 00:00:00', 'dd.mm.yyyy hh24:mi:ss') dt, 3 val from dual
union all
select 1, to_date('01.06.2013 06:00:00', 'dd.mm.yyyy hh24:mi:ss'), 10 from dual
union all
select 1, to_date('01.06.2013 12:00:00', 'dd.mm.yyyy hh24:mi:ss'), 20 from dual
union all
select 1, to_date('01.06.2013 18:00:00', 'dd.mm.yyyy hh24:mi:ss'), 18 from dual
), s as (
select id, dt, val, lead(val) over (order by dt) lead_val, 
lead(dt) over (order by dt) lead_dt
from t), r as 
(select to_date('01.06.2013 06:00:00', 'dd.mm.yyyy hh24:mi:ss') dt from dual
union all
select to_date('01.06.2013 07:00:00', 'dd.mm.yyyy hh24:mi:ss') from dual)
select r.dt, case when r.dt = s.dt then s.val else val+(lead_val-val)*((r.dt-s.dt)/(s.lead_dt-s.dt)) end intr_val
from s, r
where r.dt >= s.dt and r.dt < lead_dt 
order by r.dt
11 июн 13, 15:22    [14421160]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить