Zuerst nach einem bestimmten Feldwert sortieren


86

Ich habe eine Tabelle mit 3 Spalten:

id | name | priority
--------------------
 1 | core  |   10
 2 | core  |   9
 3 | other |   8
 4 | board |   7
 5 | board |   6
 6 | core  |   4

Ich möchte die Ergebnismenge mit priorityden Zeilen bestellen , die name=coreauch dann eine niedrigere Priorität haben. Das Ergebnis sollte so aussehen

id | name | priority
--------------------
 6 | core  |   4
 2 | core  |   9
 1 | core  |   10
 5 | board |   6
 4 | board |   7
 3 | other |   8

Antworten:


145

Es gibt auch die MySQL- FIELDFunktion .

Wenn Sie eine vollständige Sortierung für alle möglichen Werte wünschen:

SELECT id, name, priority
FROM mytable
ORDER BY FIELD(name, "core", "board", "other")

Wenn Sie sich nur darum kümmern, dass "Kern" an erster Stelle steht und die anderen Werte keine Rolle spielen:

SELECT id, name, priority
FROM mytable
ORDER BY FIELD(name, "core") DESC

Wenn Sie zuerst nach "Kern" und den anderen Feldern in normaler Sortierreihenfolge sortieren möchten:

SELECT id, name, priority
FROM mytable
ORDER BY FIELD(name, "core") DESC, priority

Hier gibt es jedoch einige Einschränkungen:

Erstens bin ich mir ziemlich sicher, dass dies nur eine MySQL-Funktion ist - die Frage ist mit MySQL gekennzeichnet, aber Sie wissen es nie.

Zweitens sollten Sie darauf achten, wie es FIELD()funktioniert: Es gibt den einbasierten Index des Werts zurück - im Fall von FIELD(priority, "core")gibt es 1 zurück, wenn "core" der Wert ist. Wenn der Wert des Feldes nicht in der Liste enthalten ist, wird Null zurückgegeben . Aus diesem Grund DESCist dies erforderlich, sofern Sie nicht alle möglichen Werte angeben.


5
Nach ungefähr 5 Jahren habe ich die akzeptierte Antwort auf diese geändert, weil sie sauberer und schneller ist.
Omid

db2 äquivalent?
Cybermonk

Es hat bei mir funktioniert, ich möchte noch eine Frage zum Umgang stellen. Wenn die Spalte 'Priorität' Werte wie z. B. 'Erdkern', 'Neue Platine' usw. enthält. Hier können wir so etwas wie eine Spalte schreiben, die keinen genauen Wert enthält %Ader%?
Jayanth Suvarna

@JayanthSuvarna: Wenn ich mir die MySQL FIELD () - Dokumente ansehe, bin ich mir ziemlich sicher, dass es keine Möglichkeit gibt, dies als Teilzeichenfolgen zu bewerten, da jedes Argument eine Art Zeichenfolge sein muss. Möglicherweise gibt es einige Funktionen zur Manipulation von Zeichenfolgen, die helfen könnten, aber ich bin mir nicht sicher.
Nerdmaster

Danke, Kumpel. Du hast meinen Tag gerettet.
BEingprabhU

91

Im Allgemeinen können Sie tun

select * from your_table
order by case when name = 'core' then 1 else 2 end,
         priority 

Besonders in MySQL können Sie das auch tun

select * from your_table
order by name <> 'core',
         priority 

Da das Ergebnis eines Vergleichs in MySQL entweder 0oder ist 1und Sie nach diesem Ergebnis sortieren können.


1
Was bedeutet 1und 2bedeutet hier?
Niraj Chauhan

1
Ich muss ungefähr 3000 Zeilen sortieren. In meinem Fall dauert die Lösung von @ Ayman-Hourieh auf stackoverflow.com/questions/958627/… im Vergleich zu dieser Lösung die Hälfte der Zeit.
Nightlyop

@nightlyop: Gut. Nur ein Hinweis: Die schnellere Lösung ist MySQL-spezifisch.
Jürgen d

1und 2sind nur 2 Zahlen, mit denen ich die Daten sortiere. Könnte sein 3und 4oder etwas anderes.
Jürgen d

Was ist, wenn es %in der WHEREKlausel gibt? Wie . . . WHERE name LIKE '%sth%' . . .? stackoverflow.com/questions/41303379/…
stack

6

Eine Möglichkeit, bestimmten Zeilen den Vorzug zu geben, besteht darin, ihrer Priorität eine große Zahl hinzuzufügen. Sie können dies mit einer CASEAussage tun :

  select id, name, priority
    from mytable
order by priority + CASE WHEN name='core' THEN 1000 ELSE 0 END desc

Demo: http://www.sqlfiddle.com/#!2/753ee/1


5

Dies funktioniert bei mir mit Postgres 9+:

SELECT *
FROM your_table
ORDER BY name = 'core' DESC, priority DESC

Möchtest du -1 erklären? Fehler + Postgres-Version?
Vojtech Vitek

3

Ein Weg ist folgender:

select id, name, priority from table a
order by case when name='core' then -1 else priority end asc, priority asc

1
Verliert das nicht die Reihenfolge der coreZeilen?
Mellamokb

1
SELECT * FROM cars_new WHERE status = '1' and car_hide !='1' and cname IN ('Executive Car','Saloon','MPV+','MPV5') ORDER BY FIELD(cname, 'Executive Car', 'Saloon','MPV+','mpv5')

3
Obwohl Ihr Code die Antwort auf die Frage sein kann, ist es besser, eine Erklärung dazu zu geben.
Mehraban

0

mach das:

SELECT * FROM table ORDER BY column `name`+0 ASC

Das Anhängen von +0 bedeutet Folgendes:

0, 10, 11, 2, 3, 4

wird :

0, 2, 3, 4, 10, 11

0

Benutze das:

SELECT * 
FROM tablename 
ORDER BY priority desc, FIELD(name, "core")
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.