2009-06-06 15 views
76

spero di ordinare gli elementi restituiti nei seguenti query nell'ordine in cui sono entrati in funzione IN().MySQL - ORDER BY valori all'interno IN()

INPUT:

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

USCITA:

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

Tutte le idee?

risposta

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

La funzione FIELD restituisce la posizione della prima stringa nella lista restante di stringhe.

Tuttavia, è molto meglio per le prestazioni avere una colonna indicizzata che rappresenta il proprio ordinamento e quindi ordinare per questa colonna.

+0

uh, è abbastanza bello! Sospetto che sia specifico per MySQL? –

+9

@Vladimir - sì, è specifico per MySQL. La domanda ha il tag mysql. –

+0

Grande, sostituzione per la funzione di "decodifica" di Oracle dopo l'interruttore DB. –

2

È necessaria un'altra colonna (numerica) nella tabella in cui si specifica l'ordinamento. La clausola IN non funziona in questo modo.

B - 1 
A - 2 
D - 3 
E - 4 
C - 5 
+1

ordine desiderato può essere per-query. –

4

Provare qualcosa di simile

... ORDER BY (CASE NAME WHEN 'B' THEN 0 WHEN 'A' THEN 1 WHEN ... 
25

Un'altra opzione da qui: 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; 

Quindi nel tuo caso (non testato) sarebbe

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'; 

seconda quello che stai facendo ho trovato un po 'eccentrico, ma sempre l'ho fatto funzionare dopo aver giocato un po 'con esso.

+0

Questo potrebbe essere meglio dell'utilizzo della funzione field() come un'altra risposta suggerita perché l'utilizzo di field() preclude l'uso dell'indice, ma ha la possibilità di usare un indice usando questo metodo (non è sicuro quanto bene possa usare l'indice, sebbene) –

+0

Questo non funziona su MySQL 5.6: http://sqlfiddle.com/#!9/9bd6c5/3. – Lacek

+1

@Lacek lo fa http://sqlfiddle.com/#!9/9bd6c5/5 – trrrrrrm

3

Può essere questo può aiutare qualcuno (p_CustomerId viene passato SP):

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; 

Descrizione: Voglio mostrare l'elenco degli account. Qui sto passando un ID cliente in sp. Ora elencherà i nomi degli account con account collegati in modo che i clienti vengano visualizzati in alto seguito da altri account in ordine alfabetico.

0

basta usare

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

evitare la situazione come

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

finirà con fila ordinata risultato: 1 e 11 alternant