ich habe eine Datenbanktabelle mit mehreren Spalten, unter anderem einer Spalte „datum1“. Die Spalte „datum1“ enthält immer einen Eintrag. Die Ausgabe wird derzeit nur nach „datum1“ sortiert:
SELECT * FROM table ORDER BY datum1
Alles läuft wunderbar.
Nun gibt es auch die Spalte „datum2“. Diese enthält nur in einzelnen Fällen einen Eintrag. Das Datum ist dann immer jünger=neuer als das Datum der Spalte „datum1“:
In diesen einzelnen Fällen, soll bei der Sortierung das neuere „datum2“ verwendet werden. Also die Einträge mit neuerem „datum2“ sollen in der Ergebnisliste dann an der Stelle auftauchen, an der sie auftauchen würden, wenn „datum1“ das neuere Datum enthalten würde. Es soll aber nur die Sortierung verändert werden, nicht die Zellinhalte:
Kann dieses Problem im Rahmen der Abfrage gelöst werden und kann mir jemand die Abfragezeile mit richtiger Syntax nennen? Ich probiere es schon seit Stunden, aber leider ohne Erfolg.
SQL kann diese Anforderung nicht erfüllen, weil sie aus Sicht des Tabellenentwurfs unsinnig ist. Sortiert werden nur Spalten, weil jede Spalte für sich eine Eigenschaft der Entität beschreibt. Sollte es mal 2 Spalten geben, die das Gleiche beschreiben, dann ist der Entwurf falsch.
Ich halte es nicht für ausgeschlossen, eine Sicht zu konstruieren, die die beiden Spalten irgendwie1 zu einer verhackstückt, diese Sicht ließe sich dann wohl sortieren. Mir wäre das allerdings zu mühsam, zumal der Tabellenentwurf mit großer Wahrscheinlichkiet weiteren Ärger machen wird.
Gruß Ralf
1Eine Möglichkeit:
Select Datum1 as Datum (, Col2, Col3, ...)
from Table
Union
Select Datum2 as Datum (, Col2, Col3, ...)
from Table
Order by Datum
Danke für die Vorschläge. Leider funktionieren sie beide nicht:
Die Lösung von drambeldier (Stichwort UNION) funktioniert nicht, weil ich die Einträge dann doppelt in der Liste habe. Das darf aber nicht sein. Und die Lösung von SomeOne (Stichwort MAX) wird nicht ausgeführt. Vom Prinzip her klingt sie allerdings ganz gut, weil ihr zufolge noch ein „interner“ Abgleich zwischen datum1 und datum2 gemacht wird, bevor ein Wert zur Sortierung herangezogen wird. Genau so muss die Lösung funktionieren (wenn es sie gibt), aber ich bekomme es nicht hin.
@drambeldier: Der vorliegende Tabellenentwurf ist zwar ungewöhnlich, aber logisch zwingend. Es handelt sich um die Dokumenten-Tabelle eines Dokumentenmanagementsystems. Jedes Dokument (z.B. ein Brief) hat ein Erstellungsdatum (datum1). Ausgehende Dokumente haben nur dieses datum1. Eingehende Dokumente haben zusätzlich noch ein Eingangsdatum (datum2), das neuer ist. Dem Nutzer muss die Lister der Dokumente chronologisch angezeigt werden und zwar so, dass eingehende Dokumente nach Eingangsdatum und ausgehende Dokumente nach Erstellungsdatum gelistet werden.
Im Prinzip könnte man diese Sortierung hinbekommen, indem man eine dritte Spalte datum3 hinzufügt, die als „Erfassungsdatum“ in dem einen Fall das datum1 der Erstellung und in dem anderen Fall das datum2 des Eingangs enthält. Diese dritte Spalte enthielte aber nur einen Wert, der sich aus den beiden anderen Spalten ermitteln lässt. Man speichert jedoch keine Werte, die sich aus anderen Werten ermitteln lassen. Das wäre höchst unprofessionell und zudem Verschwendung von Speicherplatz.
Eine andere Idee war, das „Erfassungsdatum“ der natürlichen Reihenfolge der Aufnahme der Datensätze in die Datenbank oder der Datensatznummer zu entnehmen. Denn später eingegangene Dokumente mit neuerem Eingangsdatum würden in der Datenbanktabelle auch später= weiter unten vorkommen und hätten eine höhere Datensatznummer. Leider ist diese Idee aber untauglich, weil Dokumente von mehreren Arbeitsplätzen gleichzeitig erfasst werden, sodass die Reihenfolge der Erfassung nicht zwingend chronologisch ist. Hinzu kommt, dass die Erfassung zu scannender Dokumente mitunter deutlich hinterher hinkt. Es kommt vor, dass eingegangene zu scannende Dokumente = Briefe erst dann erfasst werden, wenn der zugehörige ausgehende Brief bereits automatisch in die Datenbank eingespeichert wurde. Hierdurch wird also die Reihenfolge erheblich durcheinander gebracht. Es muss also zwingend mit Erstellungsdatum und Eingangsdatum gearbeitet werden, wobei aus gründen der Professionalität und der Speicherokonomie kein drittes Datum gespeichert werden soll.
Bei der Sortierung soll schlicht der größere Wert von datum1 und datum2 herangezogen werden. Das müsste irgendwie möglich sein und zwar auch MySQL-intern. Die „ORDER BY max(datum1,datum2)“ klingt genau nach dem, was ich suche. Nur leider wird dieser Befehl von MySQL nicht ausgeführt. Hat jemand noch eine Idee?
> Im Prinzip könnte man diese Sortierung hinbekommen, indem man eine :dritte Spalte datum3 hinzufügt, die als „Erfassungsdatum“ in dem :einen Fall das datum1 der Erstellung und in dem anderen Fall das :datum2 des Eingangs enthält. Diese dritte Spalte enthielte aber nur :einen Wert, der sich aus den beiden anderen Spalten ermitteln lässt. .Man speichert jedoch keine Werte, die sich aus anderen Werten .ermitteln lassen. Das wäre höchst unprofessionell und zudem .Verschwendung von Speicherplatz.
Das sehe ich aber nicht so , wenn das DatenbankModel dann, z.b. mit View, eine schnellere bzw überhaupt eine Verarbeitung ermöglicht, sind Felder die sich ergeben ruhig zu erstellen , solange keine redundanz eintritt ist der Geschwindikeit und Logik dem Speicherverbrauch heut zu tage vorzuziehen .
Die Lösung von drambeldier (Stichwort UNION) funktioniert
nicht, weil ich die Einträge dann doppelt in der Liste habe.
muss nicht sein:
Select Datum1 as Datum (, Col2, Col3, ...)
from Table
where Datum2 is Null
Union
Select Datum2 as Datum (, Col2, Col3, ...)
from Table
where Datum2 Not null
Order by Datum
Schau mal, ob das weiterhilft, meine nome de guerre ist Häuptling Faule Sau.
wobei aus gründen der Professionalität und der
Speicherokonomie kein drittes Datum gespeichert werden soll.
Na ja, speichern muss man sowas nicht unbedingt, nützlich sein könnte der Hilfswert in einer Query aber durchaus.
leider wird dieser Befehl von MySQL nicht ausgeführt.
Das liegt nicht an MySQL, sondern an SQL. Erfreulicherweise hält sich MySQL hier an den Standard. Max ist nun mal die Funktion, die das Maximum aus einer Spalte liefert.
Rein aus Neugier: Was sagt MySQL denn zu der Anweisung max(d1, d2)? Gibt das denn keinen Syntaxfehler?
ich habe auf einer AS400 mit DB2 die Beispieltabellen angelegt und das gepostete Statement entwickelt, es läuft wundervoll und liefert genau das vom UP geforderte Ergebnis.
Zumindest in DB2 liefert die max-Funktion auch den grössten Wert der Argumente,
in meinem Statement also "den grösseren Wert aus (datum1, datum2).
Also die Ergänzung der drambeldier-Lösung um die WHERE-Klausel zur Verhinderung doppelter Einträge funktioniert (da hätte ich auch selbst drauf kommen können). Die Abfrage ist auch nicht sonderlich verlangsamt durch UNION. Also vielen Dank.
Eleganter wäre zwar das mit MAX, aber das funktioniert in meiner Umgebung leider nicht.
Zumindest in DB2 liefert die max-Funktion auch den grössten
Wert der Argumente,
in meinem Statement also "den grösseren Wert aus (datum1,
datum2).
das kann ich nicht nachvollziehen. Dann müsste Dein SQL ja unterscheiden können zwischen der Aggregatfunktion und einer (mir völlig unbekannten) Funktion MAX, die 2 Argumente (oder sogar mehr) hat. Aus welchem Handbuch hast Du das?
Ist das vielleicht gar kein native SQL, sondern ein Schicht (ABAP?), die noch darüber liegt?
SELECT *
FROM tabelle
ORDER BY max(datum1, datum2)
;
==>
…+…1…+…2…
DATUM1 DATUM2
01.01.2012
04.01.2012
03.01.2012 06.01.2012
07.01.2012
05.01.2012 08.01.2012
09.01.2012
******** Datenende ********
Das ist also genau das gewünschte Ergebnis !
Auch die Abfrage nach dem grösseren Wert (datum1, datum2) funktioniert:
SELECT max(datum1, datum2)
FROM tabelle
;
==>
…+…1
MAX
01.01.2012
06.01.2012
04.01.2012
08.01.2012
07.01.2012
09.01.2012
******** Datenende ********
Aber was nutzt das alles, wenn MySQL es so nicht ausführt …
von daher war es lediglich ein Lösungsansatz, der nur auf der Plattform des UP nicht funktioniert . Schade, war aber einen Versuch wert .