Ordenar los resultados de una SELECT en MySQL según un valor específico
Puede haber momentos en los que se desea ordenar una consulta SQL con un orden específico que no se puede obtener utilizando ASC o DESC. MySQL tiene la función ORDER BY para ordenar los campos según el valor de una determinada columna, su uso más común es hacerlo de forma ascendente (123ABC…) o descendente (321CBA…). En este caso comentaré una forma de ordenar los resultados según un valor específico. Es decir, podremos elegir los valores por los que se ordenará esa operación DML.
Datos de ejemplo
Para esta prueba utilizaré como ejemplo una tabla llamada coches con las columnas id, marca y modelo. Soy consciente de que, en realidad, este esquema de tablas debería ser normalizado con dos tablas, una para las marcas de los coches y otra para los modelos, relacionándose en una tabla intermedia. Sin embargo, con motivo de simplificar lo haré de esta manera.
1 2 3 4 5 6 7 8 |
CREATE DATABASE pruebas; USE pruebas; CREATE TABLE coches ( id INT(10) NOT NULL AUTO_INCREMENT, marca VARCHAR(25) NOT NULL, modelo VARCHAR(50) NOT NULL, CONSTRAINT pk_coches PRIMARY KEY (id) ); |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
INSERT INTO coches (id, marca, modelo) VALUES (1, 'Seat', 'León'), (2, 'Audi', 'R8'), (3, 'BMW', 'X6'), (4, 'Audi', 'A3'), (5, 'Smart', 'Blood'), (6, 'Seat', 'Ateca'), (7, 'Seat', 'Córdoba'), (8, 'Audi', 'Q2'), (9, 'BMW', 'i8'), (10, 'Volkswagen', 'Tiguan'), (11, 'Volkswagen', 'Polo'), (12, 'Volkswagen', 'Golf'); |
Ordenar resultados por valores de campos específicos
Imaginemos que, por cualquier otro motivo, queremos ordenar el resultado arrojado de manera diferente a ascendente o descendente.
En una SELECT normal los resultados se mostrarán según hayan sido insertados en la tabla, como podemos observar al listar todos los datos de la tabla coches.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
mysql> SELECT * FROM coches; +----+------------+----------+ | id | marca | modelo | +----+------------+----------+ | 1 | Seat | León | | 2 | Audi | R8 | | 3 | BMW | X6 | | 4 | Audi | A3 | | 5 | Smart | Blood | | 6 | Seat | Ateca | | 7 | Seat | Córdoba | | 8 | Audi | Q2 | | 9 | BMW | i8 | | 10 | Volkswagen | Tiguan | | 11 | Volkswagen | Polo | | 12 | Volkswagen | Golf | +----+------------+----------+ |
Sin embargo, imaginemos que queremos que las marcas Seat, Audi y Smart sean las que encabecen la lista. La sintaxis a utilizar es simple: SELECT * FROM tabla ORDER BY FIELD (columna,'Valor1','Valor2'), 'otrovalor';
pudiendo añadir también las opciones ASC o DESC para especificar su orden.
Aplicado a nuestro esquema de tabla de pruebas sería así y queriendo obtener a Seat, Audi y Smart en primera posición sería como muestro.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
mysql> SELECT * FROM coches ORDER BY FIELD (marca,'Smart','Audi','Seat') DESC; +----+------------+----------+ | id | marca | modelo | +----+------------+----------+ | 2 | Audi | R8 | | 4 | Audi | A3 | | 8 | Audi | Q2 | | 5 | Smart | Blood | | 1 | Seat | León | | 11 | Volkswagen | Polo | | 10 | Volkswagen | Tiguan | | 9 | BMW | i8 | | 7 | Seat | Córdoba | | 6 | Seat | Ateca | | 3 | BMW | X6 | | 12 | Volkswagen | Golf | +----+------------+----------+ |
Observa que el orden descendente se realiza de derecha a izquierda y, si eliminamos la opción DESC, pasarán a ordenarse en orden invertido, siendo Seat la última.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
mysql> SELECT * FROM coches ORDER BY FIELD (marca,'Smart','Audi','Seat'); +----+------------+----------+ | id | marca | modelo | +----+------------+----------+ | 12 | Volkswagen | Golf | | 3 | BMW | X6 | | 11 | Volkswagen | Polo | | 10 | Volkswagen | Tiguan | | 9 | BMW | i8 | | 5 | Smart | Blood | | 2 | Audi | R8 | | 4 | Audi | A3 | | 8 | Audi | Q2 | | 7 | Seat | Córdoba | | 6 | Seat | Ateca | | 1 | Seat | León | +----+------------+----------+ |
¿Y el resto de campos?
El problema que esto presenta es que el resto de campos que no están especificados en la SELECT aparecerían un poco al azar. Fijémonos en la marca BMW y Volkswagen que no estarían siendo ordenados de ninguna manera lógica. ¿Cómo solucionamos esto? Fácil, volviendo a instar que se ordene por marca.
La ejecución sobre nuestro esquema de tabla de ejemplo sería así.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
mysql> SELECT * FROM coches ORDER BY FIELD (marca,'Smart','Audi','Seat') DESC, marca; +----+------------+----------+ | id | marca | modelo | +----+------------+----------+ | 1 | Seat | León | | 7 | Seat | Córdoba | | 6 | Seat | Ateca | | 4 | Audi | A3 | | 2 | Audi | R8 | | 8 | Audi | Q2 | | 5 | Smart | Blood | | 3 | BMW | X6 | | 9 | BMW | i8 | | 10 | Volkswagen | Tiguan | | 11 | Volkswagen | Polo | | 12 | Volkswagen | Golf | +----+------------+----------+ |
Igualmente, dentro de cada marca, no estaría ordenado por modelos. Si deseamos ordenar primero por marca y luego por modelo de forma ascendente (123ABC)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
mysql> SELECT * FROM coches ORDER BY FIELD (marca,'Smart','Audi','Seat') DESC, marca, modelo; +----+------------+----------+ | id | marca | modelo | +----+------------+----------+ | 6 | Seat | Ateca | | 7 | Seat | Córdoba | | 1 | Seat | León | | 4 | Audi | A3 | | 8 | Audi | Q2 | | 2 | Audi | R8 | | 5 | Smart | Blood | | 9 | BMW | i8 | | 3 | BMW | X6 | | 12 | Volkswagen | Golf | | 11 | Volkswagen | Polo | | 10 | Volkswagen | Tiguan | +----+------------+----------+ |
Nada más, espero que os haya resultado útil esta peculiar forma de utilizar ORDER BY en MySQL.
Y como haria para que solo me muestre Smart,Audi,Seat y no muestre el resto de marcas que no quiero mostrar, osea que las descarte porque no necesito mostrar las demas
Hola puedes poner un where marcas = Smart and marcas = Seat and marcas = Audi.
Hola, me gusta tu blog,tengo unas dudas, la id 7 y la 6 que son seat no están las primeras. ¿Dónde pones «Observa que el orden descendente se realiza de derecha a izquierda». Sería primero seat luego audi y por último smart, de izquierda a derecha como comentas pero no es lo que se muestra.
mysql> SELECT * FROM coches ORDER BY FIELD (marca,’Smart’,’Audi’,’Seat’) DESC;
+—-+————+———-+
| id | marca | modelo |
+—-+————+———-+
| 2 | Audi | R8 |
| 4 | Audi | A3 |
| 8 | Audi | Q2 |
| 5 | Smart | Blood |
| 1 | Seat | León |
| 11 | Volkswagen | Polo |
| 10 | Volkswagen | Tiguan |
| 9 | BMW | i8 |
| 7 | Seat | Córdoba |
| 6 | Seat | Ateca |
| 3 | BMW | X6 |
| 12 | Volkswagen | Golf |
Buenas y si la idea es mostrar un jtable en Java que tenga solo 2 columnas, «ID» y «Marca y Modelo» como sería? Gracias!
wow, que genial amigo te felicito y muchas gracias