MySQL - ORDER BY-Werte in IN ()

107

Ich hoffe, die in der folgenden Abfrage zurückgegebenen Elemente nach der Reihenfolge zu sortieren, in der sie in die Funktion IN () eingegeben wurden .

EINGANG:

SELECT id, name FROM mytable WHERE name IN ('B', 'A', 'D', 'E', 'C');

AUSGABE:

|   id   |   name  |
^--------^---------^
|   5    |   B     |
|   6    |   B     |
|   1    |   D     |
|   15   |   E     |
|   17   |   E     |
|   9    |   C     |
|   18   |   C     |

Irgendwelche Ideen?

Matt
quelle

Antworten:

231
SELECT id, name
FROM mytable
WHERE name IN ('B', 'A', 'D', 'E', 'C')
ORDER BY FIELD(name, 'B', 'A', 'D', 'E', 'C')

Die FIELD- Funktion gibt die Position der ersten Zeichenfolge in der verbleibenden Liste der Zeichenfolgen zurück.

In Bezug auf die Leistung ist es jedoch viel besser, eine indizierte Spalte zu haben, die Ihre Sortierreihenfolge darstellt, und dann nach dieser Spalte zu sortieren.

Ayman Hourieh
quelle
9
@Vladimir - ja, es ist MySQL-spezifisch. Die Frage hat das MySQL-Tag.
Ayman Hourieh
Großartig, Ersatz für die "Dekodierungs" -Funktion von Oracle nach dem DB-Wechsel.
Martin Lyne
7
Vorsichtig. Jeder unbekannte Eigenschaftswert (nicht in der Liste) hat Vorrang vor den bekannten Werten, dh FIELD(letter, 'A', 'C')die Liste gibt zuerst Einträge mit dem Buchstaben B zurück (unter der Annahme einer Reihe von Datensätzen mit A | B | CWerten). Um dies zu vermeiden, kehren Sie die Liste um und verwenden Sie DESC, d FIELD(letter, 'C', 'A') DESC. H.
Gajus
Wie erreiche ich dies in SQL Server?
user123456
29

Eine weitere Option von hier: http://dev.mysql.com/doc/refman/5.0/en/sorting-rows.html

select * 
from tablename 
order by priority='High' DESC, priority='Medium' DESC, priority='Low" DESC;

Also in deinem Fall (ungetestet) wäre

SELECT id, name
FROM mytable
WHERE name IN ('B', 'A', 'D', 'E', 'C')
ORDER BY name = 'B', name = 'A', name = 'D', name =  'E', name = 'C';

Je nachdem, was du tust, fand ich es etwas schrullig, habe es aber immer zum Laufen gebracht, nachdem ich ein bisschen damit gespielt habe.

Joedevon
quelle
Dies ist möglicherweise besser als die Verwendung der Funktion field () als weitere vorgeschlagene Antwort, da die Verwendung von field () die Indexverwendung ausschließt, es jedoch möglich ist, einen Index mit dieser Methode zu verwenden (nicht sicher, wie gut der Index verwendet werden kann).
6ıu
4

Versuchen Sie etwas wie

... ORDER BY (CASE NAME WHEN 'B' THEN 0 WHEN 'A' THEN 1 WHEN ...
Vladimir Dyuzhev
quelle
3

Möglicherweise kann dies jemandem helfen (p_CustomerId wird in SP übergeben):

SELECT CompanyAccountId, CompanyName
FROM account
LEFT JOIN customer where CompanyAccountId = customer.AccountId
GROUP BY CompanyAccountId
ORDER BY CASE WHEN CompanyAccountId IN (SELECT AccountId 
                                          FROM customer
                                          WHERE customerid= p_CustomerId) 
                 THEN 0
                 ELSE 1
          END, CompanyName;

Beschreibung: Ich möchte die Kontoliste anzeigen. Hier übergebe ich eine Kunden-ID in sp. Jetzt werden die Kontonamen mit den mit diesen Kunden verknüpften Konten oben angezeigt, gefolgt von anderen Konten in alphabetischer Reihenfolge.

Hunne
quelle
2

Sie benötigen eine weitere Spalte (numerisch) in Ihrer Tabelle, in der Sie die Sortierreihenfolge angeben. Die IN-Klausel funktioniert auf diese Weise nicht.

B - 1
A - 2
D - 3
E - 4
C - 5
Robert Harvey
quelle
2
Die gewünschte Bestellung kann pro Abfrage erfolgen.
Vladimir Dyuzhev
0

benutz einfach

order by INSTR( ',B,C,D,A,' ,  concat(',' , `field`, ',' ) )

Vermeiden Sie die Situation wie

 INSTR('1,2,3,11' ,`field`) 

endet mit einer ungeordneten Ergebniszeile: 1 und 11 alternativ

PercyQQ
quelle