ORDER BY Problem mit MySQL

Hallo zusammen,

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“:

datum 1 datum2
01.01.2012
03.01.2012 06.01.2012
04.01.2012
05.01.2012 08.01.2012
07.01.2012
09.01.2012

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:

datum 1 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

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.

Grüße,
der Marc.

Problem mit Datenmodell
Moin, Marc,

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

Hallo,

für dein Beispiel liefert

SELECT *
FROM test1
ORDER BY max(datum1, datum2)

genau das gewünschte Ergebnis.

Gruss,
SomeOne

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?

Hallo ,

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

Moin, Mark,

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?

Gruß Ralf

Hallo drambeldier,

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).

Gruss,
SomeOne

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.

Moin, SomeOne,

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?

Gruß Ralf

Guten Morgen,

„mein“ SQL ist eine IBM AS/400 mit der DB2 Datenbank, also nichts Exotisches.

Hier der durchgeführte Test bzgl. des hier geposteten Problems:

CREATE TABLE qtemp/tabelle
(datum1 char(10),
datum2 char(10) )
;

INSERT INTO qtemp/tabelle
VALUES(‚01.01.2012‘ , ’ '),
(‚03.01.2012‘ , ‚06.01.2012‘),
(‚04.01.2012‘ , ’ '),
(‚05.01.2012‘ , ‚08.01.2012‘),
(‚07.01.2012‘ , ’ '),
(‚09.01.2012‘ , ’ ')
;

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 .

Gruss,
SomeOne

einen hab ich noch
Tach zusammen,
hab das Syntax-Problem mit einem Kollegen diskutiert der MySQL hat,
er schlägt dieses vor:

SELECT *
FROM tabelle
ORDER BY Greatest( datum1, datum2 )

Kannst du das bitte mal versuchen und den Erfolg zurück melden ?

Nur so aus Neugier …

Danke,
SomeOne

update tabelle set datum3 = if(isnull(datum2),datum1,datum2);
select * from tabelle order by datum3;

Gruß FraLang