2009-06-06 24 views
76

Espero ordenar los elementos devueltos en la siguiente consulta por el orden en que se ingresan en la función IN().MySQL - ORDER BY valores dentro de()

ENTRADA:

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

SALIDA:

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

¿Alguna idea?

Respuesta

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

La función FIELD devuelve la posición de la primera cadena de la lista restante de las cadenas.

Sin embargo, es mucho mejor para el rendimiento tener una columna indexada que represente su orden de clasificación, y luego ordenar por esta columna.

+0

eh, eso es genial! Sospecho que es específico de MySQL? –

+9

@Vladimir - sí, es específico de MySQL. La pregunta tiene la etiqueta mysql. –

+0

Genial, reemplazo de la función de "decodificación" de Oracle después del cambio de DB. –

2

Necesita otra columna (numérica) en su tabla, en la que especifique el orden de clasificación. La cláusula IN no funciona de esta manera.

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

fin deseado puede ser por consulta. –

4

Pruebe algo como

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

Otra opción desde aquí: 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; 

Así, en su caso (no probado) habría

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

Dependiendo de lo que estás haciendo lo he encontrado un poco raro pero siempre Lo puso a funcionar después de jugar con él un poco.

+0

Esto puede ser mejor que usar la función field() como otra respuesta sugerida porque usar field() impedirá el uso del índice, pero tiene la posibilidad de usar un índice usando este método (aunque no está seguro de qué tan bien podría usar el índice) –

+0

Esto no funciona en MySQL 5.6: http://sqlfiddle.com/#!9/9bd6c5/3. – Lacek

+1

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

3

Puede ser que esto puede ayudar a alguien (p_CustomerId se pasa en 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; 

Descripción: Quiero mostrar la lista de cuentas. Aquí estoy pasando una identificación de cliente en sp. Ahora se enumerarán los nombres de las cuentas con cuentas vinculadas a los que los clientes se muestran en la parte superior seguido por otras cuentas en orden alfabético.

0

sólo tiene que utilizar

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

evitar la situación como

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

terminará con la fila de resultado no ordenada: 1 y 11 alternante