Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Wie kann ich mit Oracle SQL eine lineare Interpolation durchführen?

Ich bin mir nicht sicher, wie Sie PERCENTILE_CONT verwenden würden um die gewünschte Interpolation durchzuführen, aber mit Hilfe einer anderen Analysefunktion können Sie erreichen, was Sie wollen.

Zuerst erstellen wir die folgende Funktion, die INTERVAL DAY TO SECOND umwandelt Werte in Sekunden:

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;
/

Mit dieser Funktion können wir eine Abfrage wie die folgende verwenden:

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;

Ich habe Ihre Daten oben genommen, die Datumskomponente der Zeitstempel auf heute gesetzt und die folgenden Ergebnisse erhalten, als ich die obige Abfrage ausgeführt habe:

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

(Ich habe ein TO_CHAR hinzugefügt um d1.time um übermäßige Leerzeichen in SQL*Plus zu reduzieren.)

Wenn Sie DATE verwenden s anstelle von TIMESTAMP s, Sie brauchen die Funktion nicht:Sie können einfach die Daten subtrahieren.