Join mit größerem / kleinerm Wert

schalke

Benutzer
Beiträge
14
Hallo,
ich habe zwei Tabellen mit grob folgendem Aufbau



zeit | user | weitere Felder... |
----------------+------|-------------------|
20180901231520 | sbr |
20180901232016 | msc |
20180901232522 | sre |



nummer | zeit | user | vorgang |
-------+----------------+------|----------|
1000 | 20180901231410 | sbr | vorgang1 |
1000 | 20180901231622 | sbr | vorgang2 |
1000 | 20180901231701 | sbr | vorgang3 |
1001 | 20180901231220 | sre | vorgang1 |
1001 | 20180901231322 | sre | vorgang2 |
1001 | 20180901231401 | sre | vorgang3 |
1002 | 20180901233422 | msc | vorgang2 |
1002 | 20180901233501 | msc | vorgang3 |



In der ersten Tabelle sind Ereignisse, die möglichwerweise zugehörige Einträge in Tabelle 2 haben, aber nicht zwingend.

Identifitieren kann ich die Einträge aus Tabelle 2 nur anhand des Users und der Zeit.
Das heisst ich müsste einen Join haben, der mir zum Ereignis die drei (manchmal aber auch nur zwei) Datensätze aus Tabelle 2 ermittelt , die zeitlich "passen"

Join müsste etwa so, lauten:

tabelle1.user = tabelle2.user
und
tabelle1.zeit = tabelle2.zeit[rahmen]

Die Schwierigkeit für micht ist, dass die Zeiten aus tabelle1 nicht identisch mit tabelle2 sind. Es müsste also der zeitlich nächstkleinere Datensatz in tabelle2 mit Eintrag "Vorgang1" und gleichem User gefunden werden. Die restlichen Datensätze dazu bekomme ich dann über tabelle2.nummer raus.

Erschwert wird das ganze dadurch, dass die Tabellen eigentlich nicht für diese Abfrage gemacht sind und ich keinen Einfluß auf das Tabellendesign habe.

Vorab Dankeschön
Michael


 
Werbung:
was genau soll denn rauskommen? Ich versteh Dein Anliegen nicht ganz...

Code:
test=*# select * from schalke_1;
      zeit      |  usr  | weiteres_feld
----------------+-------+---------------
 20180901231520 |  sbr  |
 20180901232016 |  msc  |
 20180901232522 |  sre  |
(3 rows)

test=*# select * from schalke_2;
 nummer |      zeit      |  usr  |  vorgang   | weiteres_feld
--------+----------------+-------+------------+---------------
   1000 | 20180901231410 |  sbr  |  vorgang1  |
   1000 | 20180901231622 |  sbr  |  vorgang2  |
   1000 | 20180901231701 |  sbr  |  vorgang3  |
   1001 | 20180901231220 |  sre  |  vorgang1  |
   1001 | 20180901231322 |  sre  |  vorgang2  |
   1001 | 20180901231401 |  sre  |  vorgang3  |
   1002 | 20180901233422 |  msc  |  vorgang2  |
   1002 | 20180901233501 |  msc  |  vorgang3  |
(8 rows)

test=*# select * from schalke_1 left join (select usr, min(zeit), max(zeit) from schalke_2 group by usr) foo on schalke_1.zeit between foo.min and foo.max;
      zeit      |  usr  | weiteres_feld |  usr  |      min       |      max       
----------------+-------+---------------+-------+----------------+----------------
 20180901231520 |  sbr  |               |  sbr  | 20180901231410 | 20180901231701
 20180901232016 |  msc  |               |       |                |               
 20180901232522 |  sre  |               |       |                |               
(3 rows)

test=*# select *, row_number() over (partition by schalke_1.usr order by schalke_1.zeit-schalke_2.zeit) from schalke_1 left join schalke_2 on (schalke_1.usr=schalke_2.usr);
      zeit      |  usr  | weiteres_feld | nummer |      zeit      |  usr  |  vorgang   | weiteres_feld | row_number
----------------+-------+---------------+--------+----------------+-------+------------+---------------+------------
 20180901232016 |  msc  |               |   1002 | 20180901233501 |  msc  |  vorgang3  |               |          1
 20180901232016 |  msc  |               |   1002 | 20180901233422 |  msc  |  vorgang2  |               |          2
 20180901231520 |  sbr  |               |   1000 | 20180901231701 |  sbr  |  vorgang3  |               |          1
 20180901231520 |  sbr  |               |   1000 | 20180901231622 |  sbr  |  vorgang2  |               |          2
 20180901231520 |  sbr  |               |   1000 | 20180901231410 |  sbr  |  vorgang1  |               |          3
 20180901232522 |  sre  |               |   1001 | 20180901231401 |  sre  |  vorgang3  |               |          1
 20180901232522 |  sre  |               |   1001 | 20180901231322 |  sre  |  vorgang2  |               |          2
 20180901232522 |  sre  |               |   1001 | 20180901231220 |  sre  |  vorgang1  |               |          3
(8 rows)

Was passendes schon dabei?
 
was genau soll denn rauskommen? Ich versteh Dein Anliegen nicht ganz..

Stimmt! Hätte ich ja mal dazu schreiben können...., sorry

Ich brauche zum User und der Zeit aus Tabelle1 die zwei Vorgänge mit dem kleinsten und größtem Wert aus Tabelle2 in einer Zeile.
Der User kommt in Tabelle 1 und 2 natürlich nicht nur einmal vor, sondern tausendfach. Und es soll pro Ereignis aus Tabelle1 nur eine Ergebniszeile ausgegeben werden (mit oder ohne Werten aus Tabelle2)

Grüße
Michael
 
also so?

Code:
test=*# select
  usr
  , min(z)
  , max(z)
from (
  select
    schalke_1.*
    , schalke_2.zeit as z
    , row_number() over (partition by schalke_1.usr order by schalke_1.zeit-schalke_2.zeit) r1
    , row_number() over (partition by schalke_1.usr order by schalke_2.zeit-schalke_1.zeit) r2
  from
    schalke_1 left join schalke_2 on (schalke_1.usr=schalke_2.usr)
) foo
where r1 = 1 or r2 = 1
group by usr;
  usr  |      min       |      max       
-------+----------------+----------------
  msc  | 20180901233422 | 20180901233501
  sbr  | 20180901231410 | 20180901231701
  sre  | 20180901231220 | 20180901231401
(3 rows)

test=*#
 
Werbung:
Sieht gut aus, ich kanns aber aufgrund einer Grippe erst nächste Woche testen.
Da aber Deine Tipps immer sehr hilfreich waren, gehe ich davon aus das es klappt. Ich geb' nächste Woche Rückmeldung.

Vorab mal ein herzliches Dankeschön

Grüße
Michael
 
Zurück
Oben