Thomas Wiedmann https://twiedmann.de
• Sie befinden sich hier: Startseite > SQL-Backstube > ORDER nach verschiedenen Kriterien

Die SQL-Backstube

Bietet Rezepte, Lösungen und ausführliche Beispiele rund um gesundes SQL und zufriedene Datenbanken.

28.12.2010: ORDER nach verschiedenen Kriterien

Problemstellung

Manchmal kommen die Statistiker und Controller schon mit seltsamen Wünschen daher. Ich habe eine Tabelle mit zwei Spalten - eigentlich einfach - aber die Ausgabekriterien haben es in sich. Zudem soll das Ergebnis - aus Performancegründen - mit einem Query ermittelt werden.


Getestet mit folgender Datenbank:

* IBM DB2 9.1
* MySQL 5.1.30
* ORACLE 10g 10.2 EE


Testtabelle

Listing 1:

  1. /**
  2. * Die Tabelle
  3. */
  4. CREATE TABLE test_order (
  5. status INT NOT NULL,
  6. datum DATE NOT NULL
  7. );

Testdaten

Listing 2:

  1. /**
  2. * Testdaten (MySQL, DB2)
  3. */
  4. INSERT INTO test_order VALUES
  5. ( 0, '2010-12-01'),
  6. ( 0, '2010-12-02'),
  7. ( 0, '2010-12-03'),
  8. ( 1, '2010-12-01'),
  9. ( 1, '2010-12-02'),
  10. ( 1, '2010-12-03'),
  11. ( 1, '2010-12-04');
  12. /**
  13. * Testdaten (ORACLE)
  14. */
  15. INSERT INTO test_order VALUES ( 0, TO_DATE('2010-12-01','YYYY-MM-DD'));
  16. INSERT INTO test_order VALUES ( 0, TO_DATE('2010-12-02','YYYY-MM-DD'));
  17. INSERT INTO test_order VALUES ( 0, TO_DATE('2010-12-03','YYYY-MM-DD'));
  18. INSERT INTO test_order VALUES ( 1, TO_DATE('2010-12-01','YYYY-MM-DD'));
  19. INSERT INTO test_order VALUES ( 1, TO_DATE('2010-12-02','YYYY-MM-DD'));
  20. INSERT INTO test_order VALUES ( 1, TO_DATE('2010-12-03','YYYY-MM-DD'));
  21. INSERT INTO test_order VALUES ( 1, TO_DATE('2010-12-04','YYYY-MM-DD'));

Sortier-Kriterien

Die Daten sollen nach folgenden Kriterien sortiert werden:
1. Erst alle Einträge mit Status = 0 UND diese aufsteigend nach Datum
2. Dann alle Einträge mit Status = 1 UND diese absteigend nach Datum

Also eigentlich gegenläufige Sortierungen beim Datum und das Ganze mit einer SQL-Abfrage! Mit UNION läßt sich diese Aufgabe somit nicht lösen, da für die Teilabfragen im UNION keine eigenen Sortierungen erlaubt sind.


Die gewünschte Ausgabe..

Listing 3:

  1. +--------+------------+
  2. | status | datum |
  3. +--------+------------+
  4. | 0 | 2010-12-01 |
  5. | 0 | 2010-12-02 |
  6. | 0 | 2010-12-03 |
  7. | 1 | 2010-12-04 |
  8. | 1 | 2010-12-03 |
  9. | 1 | 2010-12-02 |
  10. | 1 | 2010-12-01 |
  11. +--------+------------+

..und die Lösung!!

Mit einem doppelten CASE und ein bißchen NULL in der ORDER BY Klausel läßt sich auch so eine exotische Ausgabe erzeugen.

Listing 4:

  1. SELECT status, datum
  2. FROM test_order
  3. ORDER BY status,
  4. CASE
  5. WHEN status = 0 THEN datum
  6. ELSE NULL
  7. END ASC,
  8. CASE
  9. WHEN status = 1 THEN datum
  10. ELSE NULL
  11. END DESC;
  12. +--------+------------+
  13. | status | datum |
  14. +--------+------------+
  15. | 0 | 2010-12-01 |
  16. | 0 | 2010-12-02 |
  17. | 0 | 2010-12-03 |
  18. | 1 | 2010-12-04 |
  19. | 1 | 2010-12-03 |
  20. | 1 | 2010-12-02 |
  21. | 1 | 2010-12-01 |
  22. +--------+------------+

Resumee

Wie das obige Beispiel sehr anschaulich zeigt, kann mit dem CASE Befehl in der ORDER BY Klausel sehr raffinierte Sortierungen realisiert werden.




Sitemap - Inhaltsverzeichnis

© 2002-2016 by Thomas Wiedmann : (Stand : 11.01.2015).