Me pregunto si hay una posibilidad (posiblemente una mejor manera) de ordenar por el orden de los valores en una cláusula IN ().
El problema es que tengo 2 consultas, una que obtiene todas las ID y la segunda que recupera toda la información. El primero crea el orden de los ID por los que quiero que el segundo ordene. Los ID se colocan en una cláusula IN () en el orden correcto.
Entonces sería algo 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 los ID se colocan 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 usando subconsultas.
Estoy usando MySQL, pero creo que podría ser útil que tenga en cuenta qué opciones hay para otros DB también.
fuente
IN
yFIELD
parámetros son iguales. Hacer esto en un código de programa puede ser más rápido al usar ese conocimiento adicional. Por supuesto, podría ser más sabio poner esta carga sobre el cliente en lugar del servidor si tiene en cuenta el rendimiento del servidor.sqlite
?Consulte a continuación cómo obtener datos ordenados.
fuente
Dos soluciones que vienen a la mente:
order by case id when 123 then 1 when 456 then 2 else null end asc
order by instr(','||id||',',',123,456,') asc
(
instr()
Es de Oracle, puede ser que tengalocate()
ocharindex()
o algo por el estilo)fuente
Ans para obtener datos ordenados.
fuente
Si desea realizar 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 unión como esta (usando la nomenclatura de OP).
Si reemplaza la declaración VALUES por otra cosa que haga lo mismo, pero en ANSI SQL, esto debería funcionar en cualquier base de datos SQL.
Nota: La segunda columna en la tabla creada (orderTbl.orderIdx) es necesaria cuando se consultan conjuntos de registros de más de 100. Originalmente no tenía una columna orderIdx, pero descubrí que con conjuntos de resultados superiores a 100 tenía que ordenar explícitamente por esa columna; en SQL Server Express 2014 de todos modos.
fuente
orderTbl.orderKey
,orderTbl.orderIndex
pororderKey
,orderIndex
funcionó muy bien
fuente
La cláusula IN describe un conjunto de valores, y los conjuntos no tienen orden.
Su solución con unir y luego ordenar en la
display_order
columna es la solución más correcta; cualquier otra cosa es probablemente un hack específico de DBMS (o está haciendo algunas cosas con las funciones OLAP en SQL estándar). Ciertamente, la unión es la solución más portátil (aunque generar los datos con losdisplay_order
valores puede ser problemático). Tenga en cuenta que es posible que deba seleccionar las columnas de pedido; eso solía ser un requisito en el SQL estándar, aunque creo que se relajó como regla hace un tiempo (tal vez hace tanto tiempo como SQL-92).fuente
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)
fuente
Utilice la función MySQL FIND_IN_SET :
fuente
Acabo de intentar hacer esto es MS SQL Server donde no tenemos FIELD ():
Tenga en cuenta que también estoy permitiendo la duplicación.
fuente
Lo primero que pensé fue escribir una sola consulta, pero dijiste que no era posible porque una es ejecutada por el usuario y la otra se ejecuta en segundo plano. ¿Cómo almacena 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:
fuente
Creo que deberías lograr almacenar tus datos de una manera que simplemente hagas una unión y sea perfecta, para que no ocurran hacks y cosas complicadas.
Tengo, por ejemplo, una lista de "ID reproducidos recientemente" de identificadores de pista, en SQLite simplemente hago:
fuente
Dale una oportunidad a esto:
Los WHERE probablemente necesitarán algunos ajustes para que las subconsultas correlacionadas funcionen correctamente, pero el principio básico debe ser sólido.
fuente