it-swarm.com.de

sql ORDER BY mehrere Werte in einer bestimmten Reihenfolge?

Ok, ich habe eine Tabelle mit einem indizierten Schlüssel und einem nicht indizierten Feld. Ich muss alle Datensätze mit einem bestimmten Wert finden und die Zeile zurückgeben. Ich würde gerne wissen, ob ich nach mehreren Werten bestellen kann.

Beispiel:

id     x_field
--     -----
123    a
124    a
125    a
126    b
127    f
128    b
129    a
130    x
131    x
132    b
133    p
134    p
135    i

pseudo: möchte das ergebnis so sortiert haben, where ORDER BY x_field = 'f', 'p', 'i', 'a'

SELECT *
FROM table
WHERE id NOT IN (126)
ORDER BY x_field 'f', 'p', 'i', 'a'

Die Ergebnisse wären also:

id     x_field
--     -----
127    f
133    p
134    p
135    i
123    a
124    a
125    a
129    a

Die Syntax ist gültig, aber wenn ich die Abfrage ausführe, werden keine Ergebnisse zurückgegeben, auch wenn ich sie auf 1 Datensatz beschränke. Gibt es einen anderen Weg, dies zu tun?

Stellen Sie sich das x_field als Testergebnis vor und ich muss alle Datensätze validieren, die in die Bedingung fallen. Ich wollte die Testergebnisse nach fehlgeschlagenen Werten ordnen, Werte übergeben. So konnte ich zuerst die fehlerhaften Werte und dann die übergebenen Werte mit ORDER BY validieren.

Was ich nicht kann:

  • GROUP BY, da ich die spezifischen Datensatzwerte zurückgeben muss
  • WO x_field IN ('f', 'p', 'i', 'a') brauche ich alle Werte, da ich versuche, eine Abfrage für mehrere Validierungstests zu verwenden. Und x_field-Werte sind nicht in DESC/ASC-Reihenfolge

Nachdem ich diese Frage geschrieben habe, beginne ich zu denken, dass ich das überdenken muss, LOL!

74
Phill Pafford
...
WHERE
   x_field IN ('f', 'p', 'i', 'a') ...
ORDER BY
   CASE x_field
      WHEN 'f' THEN 1
      WHEN 'p' THEN 2
      WHEN 'i' THEN 3
      WHEN 'a' THEN 4
      ELSE 5 --needed only is no IN clause above. eg when = 'b'
   END, id
147
gbn

Sie können einen LEFT JOIN mit "VALUES ('f', 1), ('p', 2), ('a', 3), ('i', 4)" verwenden und die zweite Spalte in Ihrer Bestellung verwenden -durch Ausdruck. Postgres verwendet einen Hash-Join, der viel schneller ist als ein riesiger CASE, wenn Sie viele Werte haben. Und es ist einfacher, automatisch zu generieren.

Wenn diese Bestellinformationen festgelegt sind, sollte sie eine eigene Tabelle haben.

24
peufeu

Versuchen:

ORDER BY x_field='F', x_field='P', x_field='A', x_field='I'

Sie waren auf dem richtigen Weg, aber indem Sie x_field nur auf den F-Wert setzen, wurden die anderen 3 als Konstanten behandelt und nicht mit irgendetwas im Datensatz verglichen.

19
Marc B

Verwenden Sie einen case -Schalter, um die Codes in Zahlen zu übersetzen, die sortiert werden können:

ORDER BY
  case x_field
  when 'f' then 1
  when 'p' then 2
  when 'i' then 3
  when 'a' then 4
  else 5
  end
12
Guffa

Ich habe dafür eine viel sauberere Lösung gefunden:

ORDER BY array_position(ARRAY['f', 'p', 'i', 'a']::varchar[], x_field)

Hinweis: array_position benötigt Postgres v9.5 oder höher.

6
rept

Die CASE und ORDER BY Vorschläge sollten alle funktionieren, aber ich werde ein Pferd mit einer anderen Farbe vorschlagen. Angenommen, es gibt nur eine vernünftige Anzahl von Werten für x_field und Sie wissen bereits, was sie sind, erstellen Sie einen Aufzählungstyp mit den Werten F, P, A und I (zuzüglich aller anderen möglichen Werte). Die Aufzählungen werden in der Reihenfolge sortiert, die in der CREATE -Anweisung angegeben ist. Sie können ausserdem aussagekräftige Wertnamen verwenden - Ihre eigentliche Anwendung hat dies wahrscheinlich getan, und Sie haben sie nur aus Gründen der Vertraulichkeit maskiert -, ohne unnötigen Speicherplatz zu verschwenden, da nur die Ordnungsposition gespeichert wird.

6
Andrew Lazarus

Sie können nach einer ausgewählten Spalte oder nach anderen Ausdrücken sortieren.

Hier ein Beispiel, wie man nach dem Ergebnis einer case-Anweisung ordnet:

  SELECT col1
       , col2
    FROM tbl_Bill
   WHERE col1 = 0
ORDER BY -- order by case-statement
    CASE WHEN tbl_Bill.IsGen = 0 THEN 0
         WHEN tbl_Bill.IsGen = 1 THEN 1
         ELSE 2 END

Das Ergebnis ist eine Liste, die mit "IsGen = 0" -Zeilen beginnt, gefolgt von "IsGen = 1" -Zeilen und allen anderen Zeilen am Ende.

Sie können am Ende weitere Bestellparameter hinzufügen:

  SELECT col1
       , col2
    FROM tbl_Bill
   WHERE col1 = 0
ORDER BY -- order by case-statement
    CASE WHEN tbl_Bill.IsGen = 0 THEN 0
         WHEN tbl_Bill.IsGen = 1 THEN 1
         ELSE 2 END,
         col1,
         col2
0
JIYAUL MUSTAPHA