Ich habe eine einfache SQL-Abfrage in PostgreSQL 8.3, die eine Reihe von Kommentaren enthält. Ich stelle dem Konstrukt in der Klausel eine sortierte Liste von Werten zur Verfügung :IN
WHERE
SELECT * FROM comments WHERE (comments.id IN (1,3,2,4));
Dies gibt Kommentare in einer beliebigen Reihenfolge zurück, die meiner Meinung nach IDs sind 1,2,3,4
.
Ich möchte, dass die resultierenden Zeilen wie die Liste im IN
Konstrukt sortiert werden : (1,3,2,4)
.
Wie erreicht man das?
sql
postgresql
sql-order-by
sql-in
Nussknacker
quelle
quelle
Antworten:
Sie können dies ganz einfach mit (in PostgreSQL 8.2 eingeführt) VALUES (), () tun.
Die Syntax sieht folgendermaßen aus:
quelle
with ordered_products as (select row_number() OVER (ORDER BY whatever) as reportingorder, id from comments) ... ORDER BY reportingorder
.Nur weil es so schwer zu finden ist und verbreitet werden muss: In mySQL kann dies viel einfacher gemacht werden , aber ich weiß nicht, ob es in anderem SQL funktioniert.
quelle
ERROR: cannot pass more than 100 arguments to a function
In Postgres 9.4 oder höher ist dies wahrscheinlich am einfachsten und schnellsten :
Mit dem neuen
WITH ORDINALITY
, das @a_horse bereits erwähnt .Wir brauchen keine Unterabfrage, wir können die Set-Return-Funktion wie eine Tabelle verwenden.
Ein String-Literal, das anstelle eines ARRAY-Konstruktors im Array übergeben werden kann, ist bei einigen Clients möglicherweise einfacher zu implementieren.
Ausführliche Erklärung:
quelle
Ich finde diesen Weg besser:
quelle
... order by id=? desc, id=? desc, id=? desc
und es scheint gut zu funktionieren :-)Mit Postgres 9.4 geht das etwas kürzer:
Oder etwas kompakter ohne abgeleitete Tabelle:
Die Notwendigkeit, jedem Wert manuell eine Position zuzuweisen / beizubehalten, entfällt.
Mit Postgres 9.6 kann dies folgendermaßen geschehen
array_position()
:Der CTE wird verwendet, damit die Werteliste nur einmal angegeben werden muss. Wenn das nicht wichtig ist, kann dies auch geschrieben werden als:
quelle
IN
Liste aus derWHERE
Klausel in derORDER BY
Klausel, was dies imho zur besten Antwort macht ... Jetzt nur, um etwas Ähnliches für MySQL zu finden ...order by array_position(array[42,48,43], c.id::int);
kann in einigen Fällen zu Fehlern führen.array_position(array[42, 48, 43]::bigint[], c.id::bigint)
, so dass keine Notwendigkeit trunkierenbigint
zuint
.Eine andere Möglichkeit, dies in Postgres zu tun, wäre die Verwendung der
idx
Funktion.Vergessen Sie nicht, zuerst die
idx
Funktion zu erstellen , wie hier beschrieben: http://wiki.postgresql.org/wiki/Array_Indexquelle
CREATE EXTENSION intarray;
.enable_extension
Sie diese Option für Amazon RDS-Benutzer aktivieren, solange Ihr App-Benutzer Mitglied derrds_superuser
Gruppe ist.In Postgresql:
quelle
position(id::text in '123,345,3,678')
. Die ID3
wird vor der ID übereinstimmen345
, nicht wahr?Als ich dies weiter recherchierte, fand ich diese Lösung:
Dies scheint jedoch ziemlich ausführlich zu sein und kann zu Leistungsproblemen bei großen Datenmengen führen. Kann jemand zu diesen Themen Stellung nehmen?
quelle
IN
Klausel Tausende von Werten enthält ? weil ich es für tausende Platten machen muss.Um dies zu tun, sollten Sie wahrscheinlich eine zusätzliche "ORDER" -Tabelle haben, die die Zuordnung der zu bestellenden IDs definiert (effektiv das, was Ihre Antwort auf Ihre eigene Frage gesagt hat), die Sie dann als zusätzliche Spalte für Ihre Auswahl verwenden können Sie können dann weiter sortieren.
Auf diese Weise beschreiben Sie explizit die gewünschte Reihenfolge in der Datenbank, wo sie sein sollte.
quelle
sans SEQUENCE, funktioniert nur unter 8.4:
quelle
oder wenn Sie das Böse dem Guten vorziehen:
quelle
Und hier ist eine andere Lösung, die funktioniert und eine konstante Tabelle verwendet ( http://www.postgresql.org/docs/8.3/interactive/sql-values.html ):
Aber ich bin mir auch nicht sicher, ob dies performant ist.
Ich habe jetzt eine Reihe von Antworten. Kann ich ein paar Stimmen und Kommentare bekommen, damit ich weiß, wer der Gewinner ist?
Danke an alle :-)
quelle
[BEARBEITEN]
unnest ist noch nicht in 8.3 integriert, aber Sie können selbst eines erstellen (die Schönheit eines jeden *):
Diese Funktion kann in jedem Typ funktionieren:
quelle
Leichte Verbesserung gegenüber der Version, die eine Sequenz verwendet, denke ich:
quelle
Hier ist [bbs] die Haupttabelle mit einem Feld namens ids, und ids ist das Array, in dem die Datei comment.id gespeichert ist.
bestanden in postgresql 9.6
quelle
Lassen Sie uns einen visuellen Eindruck von dem bekommen, was bereits gesagt wurde. Zum Beispiel haben Sie eine Tabelle mit einigen Aufgaben:
Und Sie möchten die Liste der Aufgaben nach ihrem Status sortieren. Der Status ist eine Liste von Zeichenfolgenwerten:
Der Trick besteht darin, jedem Statuswert eine Interger zu geben und die Liste numerisch zu ordnen:
Was dazu führt:
Credit @ user80168
quelle
Ich stimme allen anderen Postern zu, auf denen steht "Mach das nicht" oder "SQL ist nicht gut darin". Wenn Sie nach einer Facette von Kommentaren sortieren möchten, fügen Sie einer Ihrer Tabellen eine weitere Ganzzahlspalte hinzu, um Ihre Sortierkriterien zu speichern und nach diesem Wert zu sortieren. zB "ORDER BY comment.sort DESC" Wenn Sie diese jedes Mal in einer anderen Reihenfolge sortieren möchten, dann ... ist SQL in diesem Fall nichts für Sie.
quelle