Benötige MYSQL Query

WasserFan

Neuer Benutzer
Beiträge
2
Hallo,

ich habe eine Datenbank, mit folgendem Schema.
Schema= ID (als PK), Ankunft (datetime) und Ziel (varchar).

Ein Inhalt kann zB. wie folgt aussehen:
Zeile: 1={1,08.06.2013:15:00,Hamburg}
Zeile: 2={2,08.06.2013:15:00,Berlin}
Zeile: 3={4,08.06.2013:15:20,Hamburg}
Zeile: 4={6,08.06.2013:16:00,Berlin}
Zeile: 5={7,08.06.2013:16:30,München}
Zeile: 6={9,08.06.2013:16:35,Hamburg}

Ich benötige nun als Rückgabe eine Zweispaltige Tabelle, in der
jeweils Tupel stehen, wo jedem Zeitpunkt ein entsprechender Zeitpunkt zu geordnet wird,
wenn das gleiche Ziel erneut erreicht wurde.
Jedoch: ich benötige bestimmte Kombinationen:

-in dem Beispiel oben:
Zeile 1 und 3 /erster Umlauf von Hamburg -> Hamburg
Zeile 3 und 6 /zweiter Umlauf von Hamburg -> Hamburg
Zeile 2 und 4

Ich benötige jedoch NICHT die Verbindung von Zeile 1 zu Zeile 6.
->ich brauche also nur die Zeiten, von der jeweils kleinsten Verbindung.

Die Zieltabelle sollte dann so aussehen:
|--Zeit1--|--Zeit2--|

Aktuell schaffe ich das ganze nur, dass ich jeweils das größte Tupel bestimmte.
(also eben Zeile 1 zu Zeile 6)

Ich komme jedoch grad auf keinen grünen Trichter, wie ich das Problem nun angehen soll, um die Zwischentupel zu nehmen :/

Danke im Voraus! :)
 
Werbung:

akretschmer

Datenbank-Guru
Beiträge
9.028
Ich benötige jedoch NICHT die Verbindung von Zeile 1 zu Zeile 6.
->ich brauche also nur die Zeiten, von der jeweils kleinsten Verbindung.

Die Zieltabelle sollte dann so aussehen:
|--Zeit1--|--Zeit2--|

Aktuell schaffe ich das ganze nur, dass ich jeweils das größte Tupel bestimmte.
(also eben Zeile 1 zu Zeile 6)

Ich komme jedoch grad auf keinen grünen Trichter, wie ich das Problem nun angehen soll, um die Zwischentupel zu nehmen :/

Danke im Voraus! :)

Suchst Du sowas:

Code:
test=# select * from wasserfan ;
 id |       ankunft       |   ziel
----+---------------------+----------
  1 | 2013-06-08 15:00:00 | Hamburg
  2 | 2013-06-08 15:00:00 | Berlin
  3 | 2013-06-08 15:20:00 | Hamburg
  4 | 2013-06-08 16:00:00 | Berlin
  5 | 2013-06-08 16:30:00 | Muenchen
  6 | 2013-06-08 16:35:00 | Hamburg
(6 rows)

test=*# select *, lag(ankunft) over (partition by ziel order by ankunft) from wasserfan ;
 id |       ankunft       |   ziel   |         lag
----+---------------------+----------+---------------------
  2 | 2013-06-08 15:00:00 | Berlin   |
  4 | 2013-06-08 16:00:00 | Berlin   | 2013-06-08 15:00:00
  1 | 2013-06-08 15:00:00 | Hamburg  |
  3 | 2013-06-08 15:20:00 | Hamburg  | 2013-06-08 15:00:00
  6 | 2013-06-08 16:35:00 | Hamburg  | 2013-06-08 15:20:00
  5 | 2013-06-08 16:30:00 | Muenchen |
(6 rows)

Falls ja: die schlechte Nachricht für Dich: das geht nicht mit MySQL. Ich hab da auch keine passende Lösung.
 

ukulele

Datenbank-Guru
Beiträge
4.394
Code:
SELECT    t1.Ziel,
        t1.ankunft AS Rundenanfang,
        t2.ankunft AS Rundenende
FROM    tabelle t1
LEFT JOIN tabelle t2 ON t2.Ziel = t1.Ziel
WHERE    t1.ankunft < t2.ankunft
AND NOT EXISTS (    SELECT    1
                    FROM    tabelle t3
                    WHERE    t3.Ziel > t1.Ziel
                    AND        t3.Ziel < t2.Ziel )
Natürlich gibt es erstmal nur für jede abgeschlossene Runde einen Eintrag und die sind noch nicht sortiert aber vom prinzip her müsste das gehen.
 

akretschmer

Datenbank-Guru
Beiträge
9.028
Code:
SELECT    t1.Ziel,
        t1.ankunft AS Rundenanfang,
        t2.ankunft AS Rundenende
FROM    tabelle t1
LEFT JOIN tabelle t2 ON t2.Ziel = t1.Ziel
WHERE    t1.ankunft < t2.ankunft
AND NOT EXISTS (    SELECT    1
                    FROM    tabelle t3
                    WHERE    t3.Ziel > t1.Ziel
                    AND        t3.Ziel < t2.Ziel )
Natürlich gibt es erstmal nur für jede abgeschlossene Runde einen Eintrag und die sind noch nicht sortiert aber vom prinzip her müsste das gehen.

Das liefert aber:

Code:
test=*# SELECT    t1.Ziel,
        t1.ankunft AS Rundenanfang,
        t2.ankunft AS Rundenende
FROM    wasserfan t1
LEFT JOIN wasserfan t2 ON t2.Ziel = t1.Ziel
WHERE    t1.ankunft < t2.ankunft
AND NOT EXISTS (    SELECT    1
                    FROM    wasserfan t3
                    WHERE    t3.Ziel > t1.Ziel
                    AND        t3.Ziel < t2.Ziel );
  ziel   |    rundenanfang     |     rundenende
---------+---------------------+---------------------
 Hamburg | 2013-06-08 15:00:00 | 2013-06-08 16:35:00
 Hamburg | 2013-06-08 15:00:00 | 2013-06-08 15:20:00
 Berlin  | 2013-06-08 15:00:00 | 2013-06-08 16:00:00
 Hamburg | 2013-06-08 15:20:00 | 2013-06-08 16:35:00
(4 rows)

und damit auch (erster Dtaensatz) das, was es nicht liefern sollte ;-)
 

ukulele

Datenbank-Guru
Beiträge
4.394
Komisch, ich hab das jetzt anhand einer Log Tabelle getestet die ohne NOT EXISTS ca. 6k Ergebnisse hat und mit nur noch ca. 270, das scheint mir zu funktionieren. Unterscheidet sich deine Ausgabe mit oder ohne NOT EXISTS?
 

akretschmer

Datenbank-Guru
Beiträge
9.028
Komisch, ich hab das jetzt anhand einer Log Tabelle getestet die ohne NOT EXISTS ca. 6k Ergebnisse hat und mit nur noch ca. 270, das scheint mir zu funktionieren. Unterscheidet sich deine Ausgabe mit oder ohne NOT EXISTS?
Code:
test=*# SELECT    t1.Ziel,
        t1.ankunft AS Rundenanfang,
        t2.ankunft AS Rundenende
FROM    wasserfan t1
LEFT JOIN wasserfan t2 ON t2.Ziel = t1.Ziel
WHERE    t1.ankunft < t2.ankunft;
  ziel   |    rundenanfang     |     rundenende
---------+---------------------+---------------------
 Berlin  | 2013-06-08 15:00:00 | 2013-06-08 16:00:00
 Hamburg | 2013-06-08 15:00:00 | 2013-06-08 15:20:00
 Hamburg | 2013-06-08 15:00:00 | 2013-06-08 16:35:00
 Hamburg | 2013-06-08 15:20:00 | 2013-06-08 16:35:00
(4 rows)
 
Werbung:

ukulele

Datenbank-Guru
Beiträge
4.394
[Edit: Alles quatsch was hier stand]

...Ansonsten bin ich ratlos aber man kanns auch auf die fiese Art lösen mit einem Subquery zu jeder Zeile:
Code:
SELECT    t1.Ziel,
        t1.ankunft AS Rundenanfang,
        (    SELECT    t2.ankunft
            FROM    tabelle t2
            WHERE    t1.Ziel = t2.Ziel
            AND        t1.ankunft < t2.ankunft
            ORDER BY t2.ankunft
            LIMIT 1 ) AS Rundenende
FROM    tabelle t1
 
Oben