Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Como posso realizar interpolação linear usando Oracle SQL?


Não tenho certeza de como você usaria PERCENTILE_CONT para fazer a interpolação que você pede, mas com a ajuda de uma função analítica diferente você pode conseguir o que deseja.

Primeiramente, vamos criar a seguinte função, que converte INTERVAL DAY TO SECOND valores em segundos:
CREATE OR REPLACE FUNCTION intvl_to_seconds(
    p_interval INTERVAL DAY TO SECOND
) RETURN NUMBER DETERMINISTIC
AS
BEGIN
  RETURN EXTRACT(DAY FROM p_interval) * 24*60*60
       + EXTRACT(HOUR FROM p_interval) * 60*60
       + EXTRACT(MINUTE FROM p_interval) * 60
       + EXTRACT(SECOND FROM p_interval);
END;
/

Com esta função, podemos usar uma consulta como a seguinte:
SELECT d1.time,
       d1.value AS value1,
       q2.prev_value + intvl_to_seconds(d1.time - q2.prev_time) * (q2.next_value - q2.prev_value)/intvl_to_seconds(q2.next_time - q2.prev_time) AS value2
  FROM devices d1
  LEFT OUTER JOIN (SELECT d2.time AS prev_time,
                          d2.value AS prev_value,
                          LEAD(d2.time, 1) OVER (ORDER BY d2.time) AS next_time,
                          LEAD(d2.value, 1) OVER (ORDER BY d2.time) AS next_value
                     FROM devices d2
                    WHERE d2.deviceid = 2) q2
               ON d1.time BETWEEN q2.prev_time AND q2.next_time
 WHERE d1.deviceid = 1;

Peguei seus dados acima, configurei o componente de data dos timestamps para hoje e obtive os seguintes resultados quando executei a consulta acima:
TO_CHAR(D1.TIME)                          VALUE1     VALUE2
------------------------------------- ---------- ----------
09-SEP-11 01.00.00.000000                      1
09-SEP-11 01.00.01.000000                   1.03 552.517625
09-SEP-11 01.00.02.000000                  1.063 552.404813

(Adicionei um TO_CHAR em torno de d1.time para reduzir o espaçamento excessivo no SQL*Plus.)

Se você estiver usando DATE s em vez de TIMESTAMP s, você não precisa da função:você pode apenas subtrair as datas.