Pregunta

Si tengo algunas declaraciones de UNION como ejemplo artificial:

SELECT * FROM xxx WHERE z = 1
UNION 
SELECT * FROM xxx WHERE z = 2
UNION
SELECT * FROM xxx WHERE z = 3

¿Cuál es el comportamiento predeterminado de orden por ?

Los datos de prueba que estoy viendo esencialmente no devuelven los datos en el orden especificado anteriormente. Es decir. Los datos están ordenados, pero quería saber cuáles son las reglas de prioridad en esto.

Otra cosa es que en este caso xxx es una Vista. La vista une 3 tablas diferentes para devolver los resultados que quiero.

¿Fue útil?

Solución

No hay un orden predeterminado.

Sin una cláusula Ordenar por , el pedido devuelto no está definido. Eso significa que SQL Server puede devolverlos en el orden que desee.

EDITAR: En función de lo que he visto, sin un pedido por, el orden en el que se devuelven los resultados depende del plan de consulta. Entonces, si hay un índice que está usando, el resultado puede volver en ese orden, pero nuevamente no hay garantía.

Otros consejos

Con respecto a la adición de una cláusula ORDER BY:

Esto es probablemente elemental para la mayoría aquí, pero pensé que agregaría esto. A veces no desea que los resultados se mezclen, por lo que desea los resultados de la primera consulta, luego el segundo y así sucesivamente. Para hacer eso solo agrego una primera columna ficticia y ordeno por eso. Debido a posibles problemas con el olvido del alias de una columna en las uniones, por lo general uso ordinales en la cláusula orden por orden, no nombres de columna.

Por ejemplo:

SELECT 1, * FROM xxx WHERE z = 'abc'
UNION ALL
SELECT 2, * FROM xxx WHERE z = 'def'
UNION ALL
SELECT 3, * FROM xxx WHERE z = 'ghi'
ORDER BY 1

La columna ordinal ficticia también es útil cuando voy a realizar dos consultas y sé que solo una devolverá resultados. Entonces solo puedo verificar el ordinal de los resultados devueltos. Esto me evita tener que hacer varias llamadas a la base de datos y la mayoría de los cheques de resultados vacíos.

Acabo de encontrar la respuesta real.

Debido a que UNION elimina los duplicados, hace un DISTINTO ORDEN. Esto se hace antes de concatenar todas las declaraciones de UNION (consulte el plan de ejecución).

Para detener una ordenación, haga un UNION ALL y esto tampoco eliminará los duplicados.

Si le importa en qué orden se devuelven los registros, DEBE usar una orden de.

Si lo deja, puede aparecer organizado (según los índices elegidos por el plan de consulta), pero los resultados que ve hoy pueden NO ser los resultados que espera, e incluso podrían cambiar cuando la misma consulta se ejecute mañana.

Editar: Algunos ejemplos buenos y específicos: (todos los ejemplos son MS SQL Server)

  • el blog de Dave Pinal describe cómo dos consultas muy similares pueden mostrar un orden aparente diferente, porque se utilizan índices diferentes:

    SELECT ContactID FROM Person.Contact
    SELECT *         FROM Person.Contact
    
  • Conor Cunningham muestra cómo puede cambiar el orden aparente cuando la tabla aumenta de tamaño (si el optimizador de consultas decide utilizar un plan de ejecución paralelo).

  • Hugo Kornelis demuestra que el orden aparente no siempre se basa en la clave principal. Aquí está su publicación de seguimiento con explicación.

Una UNION puede ser engañosa con respecto al ordenamiento del conjunto de resultados porque una base de datos usará a veces un método de clasificación para proporcionar el DISTINCT que está implícito en UNION, lo que hace que parezca que las filas están ordenadas deliberadamente, esto no se aplica a UNION ALL, para el que no existe una distinción implícita, por supuesto.

Sin embargo, hay algoritmos para el distintivo implícito, como el método hash de Oracle en 10g +, para el cual no se aplicará ningún ordenamiento.

Como dice DJ, siempre use ORDENAR POR

Es muy común encontrar código mal escrito que asume que los datos de la tabla se devuelven en el orden de inserción, y el 95% del tiempo el codificador se sale con la suya y nunca se da cuenta de que esto es un problema como en muchas bases de datos comunes (MSSQL , Oracle, MySQL). Por supuesto, es una falacia completa y siempre debe corregirse cuando se detecte, y siempre, sin excepción, use una cláusula Order By.

Desde mi experiencia práctica, puede cambiar el orden usando " UNION " contra " UNION ALL " ... es decir si tu consulta es como

Select Count(*) from Table A
UNION 
Select Count(*) from Table B

result is
10
26

puede cambiar el orden reemplazando " UNION " con " UNION ALL " ... entonces el resultado será

26
10
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top