Najpierw porządkowanie według określonej wartości pola


92

Mam tabelę z 3 kolumnami:

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

Chcę uporządkować zestaw wyników za pomocą, priorityale najpierw tych wierszy, które mają name=corenawet niższy priorytet. Wynik powinien wyglądać tak

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

Odpowiedzi:


160

Jest też funkcja MySQLFIELD .

Jeśli chcesz kompletne sortowanie dla wszystkich możliwych wartości:

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

Jeśli zależy Ci tylko na tym, aby „rdzeń” był pierwszy, a inne wartości nie mają znaczenia:

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

Jeśli chcesz najpierw posortować według „rdzenia”, a pozostałe pola w normalnej kolejności:

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

Istnieją jednak pewne zastrzeżenia:

Po pierwsze, jestem prawie pewien, że to tylko funkcja mysql - pytanie jest otagowane jako mysql, ale nigdy nie wiadomo.

Po drugie, zwróć uwagę na to, jak FIELD()działa: zwraca indeks wartości ( liczony od jedynek) - w przypadku FIELD(priority, "core")zwraca 1, jeśli wartością jest „rdzeń”. Jeśli wartość pola nie znajduje się na liście, zwraca zero . Dlatego DESCjest to konieczne, chyba że określisz wszystkie możliwe wartości.


5
Po około 5 latach zmieniłem zaakceptowaną odpowiedź na tę, ponieważ jest czystsza i szybsza.
Omid

odpowiednik db2?
Cybermonk

U mnie zadziałało, chciałbym zadać jeszcze jedno pytanie o to, jak sobie poradzić Jeśli kolumna „priorytet” zawiera wartości takie jak np. „Rdzeń ziemi”, „nowa tablica” itp. Tutaj kolumna nie zawiera dokładnej wartości, czy możemy napisać coś w rodzaju %rdzeń%?
Jayanth Suvarna

@JayanthSuvarna: patrząc na dokumentację MySQL FIELD (), jestem prawie pewien, że nie ma sposobu, aby ocenić to jako podciągi, ponieważ każdy argument musi być jakimś ciągiem. Mogą istnieć pewne funkcje manipulujące na ciągach, które mogą pomóc, ale nie jestem pewien.
Nerdmaster

Dzięki stary. Uczyniłeś mój dzień.
BEingprabhU

92

Generalnie możesz to zrobić

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

Szczególnie w MySQL możesz to zrobić

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

Ponieważ wynik porównania w MySQL to albo 0albo 1i możesz sortować według tego wyniku.


1
co tu znaczy 1i co 2oznacza?
Niraj Chauhan

1
Mam około 3000 wierszy do sortowania. W moim przypadku rozwiązanie @ Ayman-Hourieh na stackoverflow.com/questions/958627/… zajmuje połowę czasu w porównaniu z tym rozwiązaniem.
nightlyop

@nightlyop: Dobry. Tylko jedna uwaga: szybsze rozwiązanie jest specyficzne dla MySQL.
juergen d

1i 2to tylko 2 liczby, których używam do sortowania danych. Może 3i 4coś innego.
juergen d

A co z sytuacją, gdy %w WHEREklauzuli jest? Lubisz . . . WHERE name LIKE '%sth%' . . .? stackoverflow.com/questions/41303379/ ...
stos

6

Jednym ze sposobów nadania pierwszeństwa określonym wierszom jest dodanie dużej liczby do ich priorytetu. Możesz to zrobić za pomocą CASEoświadczenia:

  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

To działa dla mnie przy użyciu Postgres 9+:

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

Chcesz wyjaśnić -1? Błąd + wersja Postgres?
Vojtech Vitek

3

Oto jeden sposób:

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

1
Czy to nie spowoduje utraty kolejności corerzędów?
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
Chociaż Twój kod może być odpowiedzią na to pytanie, lepiej podać jakieś wyjaśnienie.
Mehraban

0

Zrób to:

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

Dołączenie +0 oznacza, że:

0, 10, 11, 2, 3, 4

staje się :

0, 2, 3, 4, 10, 11

Ta technika służy do zamiany łańcucha na liczbę. Nie odnosi się do pytania PO. (Jednak nie widząc typu danych priority, nie mogę powiedzieć, czy powinien on być częścią kompletnego rozwiązania.)
Rick James

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.