Ich habe eine Tabelle mit mehreren Zeitreihen verschiedener Typen. Die Zeitstempel von Kohäsionspunkten aus verschiedenen Serien stimmen nicht genau überein (dh die Differenz kann bis zu einer Stunde betragen).
Schema
Unten ist das Schema mit zwei Beispielserien:
CREATE TABLE series (id integer, series_type integer, charttime timestamp,
value integer, PRIMARY KEY (id));
INSERT INTO series VALUES (1, 1, '2018-03-01 12:10:00', 40),
(2, 1, '2018-03-01 13:25:00', 30), (3, 1, '2018-03-01 14:10:00', 50);
INSERT INTO series VALUES (4, 2, '2018-03-01 11:20:00', 2), (5, 2, '2018-03-01 12:15:00', 6),
(6, 2, '2018-03-01 13:00:00', 7), (7, 2, '2018-03-01 13:45:00', 1);
id |series_type |charttime |value |
---|------------|--------------------|------|
1 |1 |2018-03-01 12:10:00 |40 |
2 |1 |2018-03-01 13:25:00 |30 |
3 |1 |2018-03-01 14:10:00 |50 |
4 |2 |2018-03-01 11:20:00 |2 |
5 |2 |2018-03-01 12:15:00 |6 |
7 |2 |2018-03-01 13:45:00 |1 |
6 |2 |2018-03-01 13:00:00 |7 |
Tor
Ziel ist es, eine Serie zusammen mit dem nächstgelegenen Datenpunkt aus einer anderen Serie auszuwählen. Für den Beispieldatensatz sollte das Ergebnis sein:
charttime |s1 |s2 |
--------------------|---|---|
2018-03-01 12:10:00 |40 |6 |
2018-03-01 13:25:00 |30 |1 |
2018-03-01 14:10:00 |50 |1 |
Erster Arbeitsansatz
Mein aktueller Ansatz besteht darin, den am besten passenden Datenpunkt aus der anderen Reihe durch eine Unterabfrage auszuwählen:
SELECT l.charttime, l.value AS s1,
( SELECT r.value
FROM series r
WHERE ABS( EXTRACT( EPOCH FROM l.charttime - r.charttime ) / 3600 ) < 1
AND r.series_type = 2
ORDER BY ABS( EXTRACT( EPOCH FROM l.charttime - r.charttime )) ASC LIMIT 1
) AS s2
FROM series l
WHERE l.series_type = 1
ORDER BY l.charttime ASC
Dies scheint nicht der beste Ansatz zu sein, da das Dataset sehr groß ist und daher die Ausführung vieler Unterabfragen die Abfrage verlangsamt.
Zweiter Ansatz
Eine andere Idee besteht darin, die Tabelle selbst zu verknüpfen und nach Zeitstempeln für geschlossene Daten zu filtern:
SELECT l.charttime, l.value AS s1, r.charttime, r.value AS s2
FROM series l, series r
WHERE abs(EXTRACT(EPOCH FROM l.charttime - r.charttime) / 3600) < 1
AND l.series_type = 1 AND r.series_type = 2
charttime |s1 |charttime |s2 |
--------------------|---|--------------------|---|
2018-03-01 12:10:00 |40 |2018-03-01 11:20:00 |2 |
2018-03-01 12:10:00 |40 |2018-03-01 12:15:00 |6 |
2018-03-01 12:10:00 |40 |2018-03-01 13:00:00 |7 |
2018-03-01 13:25:00 |30 |2018-03-01 13:45:00 |1 |
2018-03-01 13:25:00 |30 |2018-03-01 13:00:00 |7 |
2018-03-01 14:10:00 |50 |2018-03-01 13:45:00 |1 |
Das Problem sind dann die doppelten Datenpunkte. Die Gruppierung in der ersten Spalte funktioniert nicht, da die beste Übereinstimmung s2nicht ausgewählt werden kann.
Gibt es einen besseren Ansatz?
s2stammen die Werte in der Spalte von series_type= 2.
series_type = 1. Wie bereits erwähnt, s2sind die Übereinstimmungspunkte von series_type=2.