MySQL: ORDER BY condicional a una sola columna
Pregunta
Hola y gracias por tomarse el tiempo para leer esta pregunta.
Estoy utilizando MySQL, y quiero ordenar los resultados usando ORDER BY a una columna específica, pero los resultados deben estar ordenados según un criterio específico a esta columna. Por ejemplo, la siguiente tabla, quiero ORDER BY 'group'
, mostrando la primera 9,7,6 'group' items
y, en el extremo 10,8,5 'group' items
:
names group
--------- ------
susanita 10
miguelito 5
mafalda 7
manolito 8
libertad 6
felipe 9
guille 8
gracias de antemano.
Solución
SELECT* FROM mytable ORDER BY
LOCATE(CONCAT('.',`group`,'.'),'.9.7.6.10.8.5.');
Tomé datos de la muestra, lo cargó en una tabla denominada mitabla y corrí a él.
Estos son los resultados:
mysql> use test
Database changed
mysql> drop table if exists mytable;
Query OK, 0 rows affected (0.04 sec)
mysql> create table mytable
-> (
-> names varchar(10),
-> `group` int
-> );
Query OK, 0 rows affected (0.08 sec)
mysql> insert into mytable values
-> ('susanita', 10),
-> ('miguelito', 5),
-> ('mafalda', 7),
-> ('manolito', 8),
-> ('libertad', 6),
-> ('felipe', 9),
-> ('guille', 8);
Query OK, 7 rows affected (0.09 sec)
Records: 7 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM mytable;
+-----------+-------+
| names | group |
+-----------+-------+
| susanita | 10 |
| miguelito | 5 |
| mafalda | 7 |
| manolito | 8 |
| libertad | 6 |
| felipe | 9 |
| guille | 8 |
+-----------+-------+
7 rows in set (0.00 sec)
mysql> SELECT * FROM mytable ORDER BY
-> LOCATE(CONCAT('.',`group`,'.'),'.9.7.6.10.8.5.');
+-----------+-------+
| names | group |
+-----------+-------+
| felipe | 9 |
| mafalda | 7 |
| libertad | 6 |
| susanita | 10 |
| manolito | 8 |
| guille | 8 |
| miguelito | 5 |
+-----------+-------+
7 rows in set (0.01 sec)
mysql>
darle una oportunidad !!!
ACTUALIZACIÓN 2011-09-06 12:33 EDT
Aquí es otro enfoque:
SELECT* FROM mytable ORDER BY
IF(FIELD(`group`,9,7,6,10,8,5)=0,99999,FIELD(`group`,9,7,6,10,8,5));
Esto obligará a ningún grupo que no sean 9,7,6,10,8,5 a aparecer en la parte inferior de la consulta.
ACTUALIZACIÓN 2011-09-06 14:39 EDT
mysql> SELECT names, `group`
-> FROM mytable
-> WHERE `group` IN (9,7,6,10,8,5)
-> ORDER BY find_in_set(`group`,'9,7,6,10,8,5');
+-----------+-------+
| names | group |
+-----------+-------+
| felipe | 9 |
| mafalda | 7 |
| libertad | 6 |
| susanita | 10 |
| manolito | 8 |
| guille | 8 |
| miguelito | 5 |
+-----------+-------+
7 rows in set (0.00 sec)
Hey @ Nick, el suyo funciona tan bien en contra de mis datos de la muestra !!!
Otros consejos
El uso de MySQL es find_in_set()
función para hacer esto. Es más concisa pero menos portátiles que en el caso acercarse gbn propuesto.
SELECT `names`, `group`
FROM my_table
WHERE `group` IN (9,7,6,10,8,5)
ORDER BY find_in_set(`group`,'9,7,6,10,8,5');
Debido a que se basa en la búsqueda de cadenas, find_in_set()
es útil principalmente para los pedidos en pequeños juegos de llaves fácilmente investigables, como números enteros.
Por lo general (que ha pedido a diario en SO) que tendría que utilizar un caso que es el estándar SQL
ORDER BY
CASE group
WHEN 9 THEN 1
WHEN 7 THEN 2
WHEN 6 THEN 3
WHEN 10 THEN 4
WHEN 8 THEN 5
WHEN 5 THEN 6
ELSE 7
END
Yo estaría interesado en ver cómo se compara lo largo de un gran conjunto de datos con el método LOCALIZAR (CONCAT ...) de RolandoMySQLDBA
En un ejemplo más complejo, ver 'Conversión falló error con la expresión ORDER BY CASO
You could create it as an ENUM type.
ENUM values are sorted according to the order in which the enumeration members were listed in the column specification. (In other words, ENUM values are sorted according to their index numbers.) For example, 'a' sorts before 'b' for ENUM('a', 'b'), but 'b' sorts before 'a' for ENUM('b', 'a').
So create the ENUM field as ENUM('9','7','6','10','8','5')
Disclaimer: I do not endorse this, because I suspect that your group
column needs to be dynamic. I am just mentioning it as an option.