2012-12-31 12 views
48

określonej wartości pola Mam tabeli z 3 kolumny:zamawiania przez pierwszy

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

Chcę zamówić zestaw wyników przy użyciu priority ale najpierw te wiersze, które mają name=core nawet jeśli mają 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 

Odpowiedz

57

Istnieje również MySQL FIELD function.

Jeśli chcesz pełną sortowania dla wszystkich możliwych wartości:

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

Jeśli tylko obchodzi, że „rdzeń” jest pierwszym i inne wartości nie mają znaczenia:

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

Jeśli chcesz aby sortować według "rdzenia" najpierw, a inne pola w normalnej kolejności sortowania:

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

Jest kilka zastrzeżeń tutaj jednak:

Po pierwsze, jestem pewien, że jest to funkcjonalność tylko dla MySQL - pytanie jest oznaczone mysql, ale nigdy nie wiadomo.

Po drugie, należy zwrócić uwagę na to, jak FIELD() prac: zwraca indeks wartości z jeden własnych - w przypadku FIELD(priority, "core"), będzie to zwraca 1 jeśli „core” jest wartością. Jeśli wartość pola nie znajduje się na liście, zwraca zero. Dlatego konieczne jest podanie DESC, chyba że podasz wszystkie możliwe wartości.

+3

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

+0

ekwiwalent db2? – Cybermonk

3

Jednym ze sposobów jest to:

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 rzędów "podstawowych"? – mellamokb

+1

@mellamokb nie, z moją edycją;) – Icarus

6

Jednym ze sposobów, aby dać pierwszeństwo do konkretnych wierszy jest dodanie dużej liczby ich priorytetu. Można to zrobić z CASE stwierdzeniem:

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

79

Generalnie można zrobić

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

Zwłaszcza w MySQL można też zrobić

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

Ponieważ wynikiem porównania w MySQL jest 0 lub 1 i możesz sortować według tego wyniku.

+5

+1 Dużo czystsze rozwiązanie niż moje :) – mellamokb

+1

co znaczy "1" i "2"? –

+1

Mam około 3000 wierszy do sortowania. W moim przypadku rozwiązanie @ Ayman-Hourieh na http://stackoverflow.com/questions/958627/mysql-order-by-values-within-in zajmuje połowę czasu w porównaniu do tego rozwiązania. – nightlyop

1

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

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

Chcesz wyjaśnić -1? Błąd + wersja PostgreS? –

0

to zrobić:

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

Dołączenie +0 oznacza, że:

0, 10, 11, 2, 3, 4 

staje:

0, 2, 3, 4, 10, 11 
2
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 pytanie, lepiej podać wyjaśnienie na jego temat. – Mehraban

Powiązane problemy