Non sono sicuro di come useresti PERCENTILE_CONT
per fare l'interpolazione che chiedi, ma con l'aiuto di una diversa funzione analitica puoi ottenere ciò che vuoi.
Per prima cosa, creeremo la seguente funzione, che converte INTERVAL DAY TO SECOND
valori in secondi:
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;
/
Con questa funzione possiamo utilizzare una query come la seguente:
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;
Ho preso i tuoi dati sopra, ho impostato il componente data dei timestamp su oggi e ho ottenuto i seguenti risultati quando ho eseguito la query sopra:
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
(Ho aggiunto un TO_CHAR
intorno a d1.time
per ridurre la spaziatura eccessiva in SQL*Plus.)
Se stai usando DATE
s invece di TIMESTAMP
s, non hai bisogno della funzione:puoi semplicemente sottrarre le date.