2012-12-31 12 views
48

Ho una tabella con 3 colonne:Ordinamento per valore specifico campo prima

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

voglio ordinare di risultati utilizzando priority ma prima le righe che presentano name=core anche se hanno priorità inferiore. Il risultato dovrebbe essere simile a questo modo

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

risposta

57

C'è anche il MySQL FIELD function.

Se volete ordinamento completo per tutti i possibili valori:

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

Se vi interessa soltanto che "core" è il primo e gli altri valori non contano:

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

Se si desidera ordinare prima per "core" e gli altri campi nell'ordine normale:

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

Ci sono alcuni avvertimenti qui, però:

In primo luogo, sono abbastanza sicuro che questa è solo funzionalità mysql - la domanda è codificata mysql, ma non si sa mai.

In secondo luogo, prestare attenzione a come FIELD() opere: restituisce l'indice uno a base del valore - nel caso di FIELD(priority, "core"), che restituisca 1 se "core" è il valore. Se il valore del campo non è nell'elenco, restituisce zero. Questo è il motivo per cui è necessario DESC se non si specificano tutti i valori possibili.

+3

Dopo circa 5 anni ho cambiato risposta accettata a questo perché è più pulito e veloce. – Omid

+0

equivalente db2? – Cybermonk

3

Uno è questo:

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

Questo non perderà l'ordine delle righe 'core'? – mellamokb

+1

@mellamokb no, con la mia modifica;) – Icarus

6

Un modo per dare la preferenza a righe specifiche è quello di aggiungere un gran numero di loro priorità. È possibile farlo con una dichiarazione CASE:

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

In generale si può fare

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

Soprattutto in MySQL si può anche fare

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

Dal momento che la il risultato di un confronto in MySQL è 0 o 1 e puoi ordinare in base a quel risultato.

+5

+1 Molto più pulita della mia :) – mellamokb

+1

cosa significa '1' e' 2' significa qui? –

+1

Ho circa 3000 righe da ordinare. Nel mio caso la soluzione di @ Ayman-Hourieh su http://stackoverflow.com/questions/958627/mysql-order-by-values-within-in richiede la metà del tempo rispetto a questa soluzione. – nightlyop

1

Questo funziona per me utilizzando Postgres 9+:

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

Cura di spiegare -1? Errore + versione Postgres? –

0

fare questo:

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

Aggiunta la +0 significherà che:

0, 10, 11, 2, 3, 4 

diventa:

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

Sebbene il codice possa essere la risposta alla domanda, è meglio fornire alcune spiegazioni al riguardo. – Mehraban

Problemi correlati