String (Timestamp) auf den nächst-kleineren vergleichen

Hallo,

ich brauche mal wieder euche Hilfe…

Gegeben ist folgendes:
PostgreSQL 8.4

--Eine Wertetabelle:
CREATE TABLE T1 
(
  id INTEGER DEFAULT nextval( 'T1_id_seq' ) NOT NULL PRIMARY KEY;
  time timestamp NOT NULL,
  value DOUBLE PRECISION
);

--Und eine  Grenzwerttabelle:
CREATE TABLE T2 
(
  id INTEGER DEFAULT nextval( 'T2_id_seq' ) NOT NULL PRIMARY KEY;
  time timestamp NOT NULL,
  ugw DOUBLE PRECISION, 
  ogw DOUBLE PRECISION
);

Diese Daten sind vorhanden:

select * from T1;
id | time | value
----±-------------------------±----------
1 | 2013-02-01 09:00:00 | 4.89
2 | 2013-02-02 09:00:00 | 5.45
3 | 2013-02-03 09:00:00 | 6.65
4 | 2013-02-04 09:00:00 | 5.65
5 | 2013-02-05 09:00:00 | 4.24

select * from T2;
id | time | ugw | ogw
----±-------------------------±----------±-----------
1 | 2013-02-01 08:08:45 | 1 | 6
2 | 2013-02-03 09:01:00 | 1.4 | 7
3 | 2013-02-04 08:07:30 | 1.2 | 6.5


Und ich brauche eine Abfrage die folgendes ausgibt:
time_t1 | time_t2 | value | ugw | ogw
--------------------------±--------------------------±-----------±---------±----------
2013-02-01 09:00:00 | 2013-02-01 08:08:45 | 4.89 | 1 | 6
2013-02-02 09:00:00 | 2013-02-01 08:08:45 | 5.45 | 1 | 6
2013-02-03 09:00:00 | 2013-02-01 08:08:45 | 6.65 | 1 | 6
2013-02-04 09:00:00 | 2013-02-03 09:01:00 | 5.65 | 1.4 | 7
2013-02-05 09:00:00 | 2013-02-04 08:07:30 | 4.24 | 1.2 | 6.5


T2 joint T1
Alle ‘value’ von T1 werden ausgegeben (nicht mehrfach, alle Werte nur einmal ausgeben)
Alle ‘ugw’ und ‘ogw’ die als letztes in T2 stehen, die aber noch vom Zeitstempel her der nächst-niedigere ist als in T1.

Hintergrund:
Die Werte werden von mir danach in eine csv exportiert.
Die Exportierte csv wird in Excel geladen.
Ein Diagramm wird erzeugt welches die Werte darstellt.
Die Grenzwertänderungen sollen dann gut ablesbar sein.

Hier ein Beispiel (sind andere Werte als ich in den Beispieltabellen oben verwendet habe) :

Gibt es eine Möglichkeit dies mit der Version 8.4 zu lösen?

Gruß

Deine Tabellendefinitionen sind syntaktisch falsch. Das gibt schon mal massig Minuspunkte.




Diese Daten sind vorhanden:

select * from T1;
id | time | value
----±-------------------------±----------
1 | 2013-02-01 09:00:00 | 4.89
2 | 2013-02-02 09:00:00 | 5.45
3 | 2013-02-03 09:00:00 | 6.65
4 | 2013-02-04 09:00:00 | 5.65
5 | 2013-02-05 09:00:00 | 4.24

select * from T2;
id | time | ugw | ogw
----±-------------------------±----------±-----------
1 | 2013-02-01 08:08:45 | 1 | 6
2 | 2013-02-03 09:01:00 | 1.4 | 7
3 | 2013-02-04 08:07:30 | 1.2 | 6.5


Und ich brauche eine Abfrage die folgendes ausgibt:
time_t1 | time_t2 | value | ugw | ogw
--------------------------±--------------------------±-----------±---------±----------
2013-02-01 09:00:00 | 2013-02-01 08:08:45 | 4.89 | 1 | 6
2013-02-02 09:00:00 | 2013-02-01 08:08:45 | 5.45 | 1 | 6
2013-02-03 09:00:00 | 2013-02-01 08:08:45 | 6.65 | 1 | 6
2013-02-04 09:00:00 | 2013-02-03 09:01:00 | 5.65 | 1.4 | 7
2013-02-05 09:00:00 | 2013-02-04 08:07:30 | 4.24 | 1.2 | 6.5
[/quote]

Definiere die Regel, wie Du auf diese Resultate kommen willst. Man kann hier nur rätseln.

test=*# select * from t1;
 id |        time         | value 
----+---------------------+-------
  1 | 2013-02-01 09:00:00 |  4.89 
  2 | 2013-02-02 09:00:00 |  5.54
  3 | 2013-02-03 09:00:00 |  6.65
  4 | 2013-02-04 09:00:00 |  5.65
  5 | 2013-02-05 09:00:00 |  4.24
(5 rows)

Time: 0,175 ms
test=*# select * from t2;
 id |        time         | ugw | ogw
----+---------------------+-----+-----
  1 | 2013-02-01 08:08:45 |   1 |   6
  2 | 2013-02-03 09:01:00 | 1.4 |   7
  3 | 2013-02-04 08:07:30 | 1.2 | 6.5
(3 rows)

Time: 0,173 ms
test=*# select t1.time, t2.time, t1.value, t2.ugw, t2.ogw from t1 left join t2 on t1.value between t2.ugw and t2.ogw;        time         |        time         | value | ugw | ogw
---------------------+---------------------+-------+-----+-----
 2013-02-01 09:00:00 | 2013-02-01 08:08:45 |  4.89 |   1 |   6
 2013-02-01 09:00:00 | 2013-02-03 09:01:00 |  4.89 | 1.4 |   7
 2013-02-01 09:00:00 | 2013-02-04 08:07:30 |  4.89 | 1.2 | 6.5
 2013-02-02 09:00:00 | 2013-02-01 08:08:45 |  5.54 |   1 |   6
 2013-02-02 09:00:00 | 2013-02-03 09:01:00 |  5.54 | 1.4 |   7
 2013-02-02 09:00:00 | 2013-02-04 08:07:30 |  5.54 | 1.2 | 6.5
 2013-02-03 09:00:00 | 2013-02-03 09:01:00 |  6.65 | 1.4 |   7
 2013-02-04 09:00:00 | 2013-02-01 08:08:45 |  5.65 |   1 |   6
 2013-02-04 09:00:00 | 2013-02-03 09:01:00 |  5.65 | 1.4 |   7
 2013-02-04 09:00:00 | 2013-02-04 08:07:30 |  5.65 | 1.2 | 6.5
 2013-02-05 09:00:00 | 2013-02-01 08:08:45 |  4.24 |   1 |   6
 2013-02-05 09:00:00 | 2013-02-03 09:01:00 |  4.24 | 1.4 |   7
 2013-02-05 09:00:00 | 2013-02-04 08:07:30 |  4.24 | 1.2 | 6.5
(13 rows)

Time: 0,368 ms
test=*# select distinct on (t1.time) t1.time, t2.time, t1.value, t2.ugw, t2.ogw from t1 left join t2 on t1.value between t2.ugw and t2.ogw order by t1.time, t2.time asc;
        time         |        time         | value | ugw | ogw
---------------------+---------------------+-------+-----+-----
 2013-02-01 09:00:00 | 2013-02-01 08:08:45 |  4.89 |   1 |   6
 2013-02-02 09:00:00 | 2013-02-01 08:08:45 |  5.54 |   1 |   6
 2013-02-03 09:00:00 | 2013-02-03 09:01:00 |  6.65 | 1.4 |   7
 2013-02-04 09:00:00 | 2013-02-01 08:08:45 |  5.65 |   1 |   6
 2013-02-05 09:00:00 | 2013-02-01 08:08:45 |  4.24 |   1 |   6
(5 rows)

Time: 0,370 ms

Fast das, was Du willst, oder?

Die ‘Regel’ wäre verbal so formuliert:

Gebe mir alle
t1.time
t2.time
t1.value
t2.ugw
t2.ogw

wobei
das Pärchen t1.time t1.value nur einmal vorkommt
und t2.Datensatz der Datensatz sein muss dessen t2.time innerhalb von t2 der größte Wert und aber noch kleiner als der t1.time Wert ist.


so in etwa wie:

select distinct on (t1.time, t1.value)
t1.time, max(t2.time)-1, t1.value, t2.ugw, t2.ogw;

das -1 soll sich auf Datensätze beziehen.

Irgendwie steig ich nich durch, sorry. Vielleicht suchst Du lag(), was auf einen Datensatz vorher verweist, aber dazu muß man eine Sortierung definieren.