Information ausblenden
Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm

Join mit größerem / kleinerm Wert

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von schalke, 8 September 2018.

  1. schalke

    schalke Benutzer

    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


     
  2. akretschmer

    akretschmer Datenbank-Guru

    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?
     
  3. schalke

    schalke Benutzer

    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
     
  4. akretschmer

    akretschmer Datenbank-Guru

    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=*#
    
     
  5. schalke

    schalke Benutzer

    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
     
    akretschmer gefällt das.
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden