varias registros por ordenar orden fecha descendente columnas mysql sql sql-order-by

registros - ordenar por varias columnas mysql



Ordenar por orden de valores en una cláusula SQL IN() (13)

Me pregunto si hay una forma (posiblemente mejor) de ordenar por el orden de los valores en una cláusula IN ().

El problema es que tengo 2 consultas, una que obtiene todos los ID y la segunda que recupera toda la información. El primero crea el orden de los ID que deseo que el segundo ordene. Los ID se colocan en una cláusula IN () en el orden correcto.

Entonces sería algo así como (extremadamente simplificado):

SELECT id FROM table1 WHERE ... ORDER BY display_order, name SELECT name, description, ... WHERE id IN ([id''s from first])

El problema es que la segunda consulta no devuelve los resultados en el mismo orden en que se colocan los ID en la cláusula IN ().

Una solución que he encontrado es poner todos los ID en una tabla temporal con un campo de incremento automático que luego se une a la segunda consulta.

¿Hay alguna opción mejor?

Nota: Como la primera consulta se ejecuta "por el usuario" y la segunda se ejecuta en un proceso en segundo plano, no hay forma de combinar la consulta 2 en 1 mediante subconsultas.

Estoy usando MySQL, pero estoy pensando que podría ser útil hacer notar qué opciones hay para otros DB también.


Ans para obtener los datos ordenados.

SELECT ... FROM ... ORDER BY FIELD(user_id,5,3,2,...,50) LIMIT 10


Consulte cómo obtener datos ordenados.

SELECT ... FROM ... WHERE zip IN (91709,92886,92807,...,91356) AND user.status=1 ORDER BY provider.package_id DESC , FIELD(zip,91709,92886,92807,...,91356) LIMIT 10


Creo que deberías poder almacenar tus datos de una manera que simplemente te unirás y será perfecto, así que no habrá intromisiones y cosas complicadas.

Tengo, por ejemplo, una lista de ID de seguimiento "recientemente reproducida", en SQLite simplemente lo hago:

SELECT * FROM recently NATURAL JOIN tracks;


Dale una oportunidad:

SELECT name, description, ... WHERE id IN (SELECT id FROM table1 WHERE...) ORDER BY (SELECT display_order FROM table1 WHERE...), (SELECT name FROM table1 WHERE...)

Los WHERE probablemente necesitarán un pequeño ajuste para que las subconsultas correlacionadas funcionen correctamente, pero el principio básico debería ser el sonido.


Dos soluciones que vienen a la mente:

  1. order by case id when 123 then 1 when 456 then 2 else null end asc

  2. order by instr('',''||id||'','','',123,456,'') asc

( instr() es de Oracle, tal vez tiene locate() o charindex() o algo así)


Intenté hacer esto: MS SQL Server, donde no tenemos FIELD ():

SELECT table1.id ... INNER JOIN (VALUES (10,1),(3,2),(4,3),(5,4),(7,5),(8,6),(9,7),(2,8),(6,9),(5,10) ) AS X(id,sortorder) ON X.id = table1.id ORDER BY X.sortorder

Tenga en cuenta que también estoy permitiendo la duplicación.


La cláusula IN describe un conjunto de valores y los conjuntos no tienen orden.

Su solución con una combinación y luego ordenando en la columna display_order es la solución más correcta; cualquier otra cosa es probablemente un truco específico de DBMS (o está haciendo algunas cosas con las funciones OLAP en SQL estándar). Ciertamente, la combinación es la solución más portátil (aunque generar los datos con los valores de display_order puede ser problemático). Tenga en cuenta que puede necesitar seleccionar las columnas de pedido; eso solía ser un requisito en SQL estándar, aunque creo que fue relajado como una regla hace un tiempo (tal vez hace tanto tiempo como SQL-92).


Mi primer pensamiento fue escribir una sola consulta, pero dijiste que no era posible porque una la ejecuta el usuario y la otra se ejecuta en segundo plano. ¿Cómo está almacenando la lista de identificadores para pasar del usuario al proceso en segundo plano? ¿Por qué no ponerlos en una tabla temporal con una columna para indicar el orden?

Entonces, ¿qué tal esto?

  1. El bit de la interfaz de usuario se ejecuta e inserta valores en una nueva tabla que cree. Insertaría la identificación, la posición y algún tipo de identificador de número de trabajo)
  2. El número de trabajo se pasa al proceso de fondo (en lugar de todos los identificadores)
  3. El proceso en segundo plano selecciona de la tabla en el paso 1 y se une para obtener la otra información que necesita. Utiliza el número de trabajo en la cláusula WHERE y las órdenes en la columna de posición.
  4. El proceso en segundo plano, cuando termina, se elimina de la tabla según el identificador del trabajo.

Para Oracle, la solución de John que utiliza la función instr () funciona. Aquí hay una solución ligeramente diferente que funcionó: SELECT id FROM table1 WHERE id IN (1, 20, 45, 60) ORDER BY instr(''1, 20, 45, 60'', id)


Si desea hacer una ordenación arbitraria en una consulta utilizando los valores ingresados ​​por la consulta en MS SQL Server 2008+ , puede hacerlo creando una tabla sobre la marcha y haciendo una combinación como tal (usando la nomenclatura de OP).

SELECT table1.name, table1.description ... FROM (VALUES (id1,1), (id2,2), (id3,3) ...) AS orderTbl(orderKey, orderIdx) LEFT JOIN table1 ON orderTbl.orderKey=table1.id ORDER BY orderTbl.orderIdx

Si reemplaza la instrucción VALUES con otra cosa que hace lo mismo, pero en ANSI SQL, entonces esto debería funcionar en cualquier base de datos SQL.

Nota: La segunda columna de la tabla creada (orderTbl.orderIdx) es necesaria cuando se consultan conjuntos de registros de más de 100 o más. Originalmente no tenía una columna orderIdx, pero descubrí que con conjuntos de resultados mayores a 100 tenía que ordenar explícitamente por esa columna; en SQL Server Express 2014 de todos modos.


Use la función FIELD() MySQL:

SELECT name, description, ... FROM ... WHERE id IN([ids, any order]) ORDER BY FIELD(id, [ids in order])

FIELD() devolverá el índice del primer parámetro que es igual al primer parámetro (que no sea el primer parámetro en sí).

FIELD(''a'', ''a'', ''b'', ''c'')

regresará 1

FIELD(''a'', ''c'', ''b'', ''a'')

regresará 3

Esto hará exactamente lo que quiera si pega los identificadores en la cláusula IN() y la función FIELD() en el mismo orden.


Use la función FIND_IN_SET MySQL:

SELECT * FROM table_name WHERE id IN (..,..,..,..) ORDER BY FIND_IN_SET (coloumn_name, .., .., ..);


SELECT ORDER_NO, DELIVERY_ADDRESS from IFSAPP.PURCHASE_ORDER_TAB where ORDER_NO in (''52000077'',''52000079'',''52000167'',''52000297'',''52000204'',''52000409'',''52000126'') ORDER BY instr(''52000077,52000079,52000167,52000297,52000204,52000409,52000126'',ORDER_NO)

funcionó realmente genial