2011-06-17 26 views
41

Encontré un montón de preguntas sobre este tema con buenas soluciones, pero ninguna de ellas realmente trata qué hacer si los datos no se ordenan de una manera específica. Por ejemplo, la siguiente consulta:Función SQL Row_Number() en Where Clause without ORDER BY?

WITH MyCte AS 
(
    select employee_id, 
      RowNum = row_number() OVER (order by employee_id) 
    from  V_EMPLOYEE 
    ORDER BY Employee_ID 
) 
SELECT employee_id 
FROM MyCte 
WHERE RowNum > 0 

funciona bien si los datos se ordenan por employee_id. Pero, ¿qué pasa si mis datos no tienen un orden específico pero los números de las filas actúan como una identificación? Mi objetivo es escribir una consulta como la siguiente (con la función Row_Number() tener ninguna cláusula ORDER BY):

WITH MyCte AS 
(
    select employee_id, 
      RowNum = row_number() OVER (<PRESERVE ORIGINAL ORDER FROM DB>) 
    from  V_EMPLOYEE 
    ORDER BY Employee_ID 
) 
SELECT employee_id 
FROM MyCte 
WHERE RowNum > 0 

EDIT: Al buscar en Google, me di cuenta de que esto no es realmente posible. ¿Pueden algunos sugerir una solución para esto?

+5

A menos que tenga una cláusula explícita 'ORDEN BY', no es ** ** NO orden implícito (no hay una "orden original de DB ") en un entorno de SQL Server –

+0

@marc_s: Gracias. Solo para aclarar, ¿quiere decir que, en una pequeña base de datos de, por ejemplo, 20000 registros, no conserva el orden de inserción (aunque no hay inserciones simultáneas)? – Legend

+1

@marc_s: +1 Tienes razón. Incluso durante inserciones secuenciales, no conserva el orden. Esto es bastante diferente de mi experiencia MySQL. ¡Gracias por el aviso! – Legend

Respuesta

92

Por si acaso es útil para otra persona. Sólo pensé que fuera de elsewhere:

WITH MyCte AS 
(
    select employee_id, 
      RowNum = row_number() OVER (ORDER BY (SELECT 0)) 
    from  V_EMPLOYEE 
    ORDER BY Employee_ID 
) 
SELECT employee_id 
FROM MyCte 
WHERE RowNum > 0 
+0

Si considera que esta es la respuesta adecuada, debe marcarla como tal. De esta forma, la pregunta se marcará correctamente como respondida y otros podrán encontrar esta solución con más éxito. – mtazva

+0

@mtazava: En realidad, me gustaría darle algo de tiempo (de todos modos tiene un requisito de esperar 2 días antes de aceptar mi propia respuesta :)). El problema es que no soy un experto en SQL Server y escucho que algunas personas dicen que el enfoque en sí no se debe seguir porque no se puede garantizar el orden. – Legend

+8

PEDIDO POR (SELECCIONAR 0) no garantiza el orden correcto. Ver http: // stackoverflow.com/questions/9737131/sql-server-join-in-order – Egor4eg

4

No hay tal cosa como el orden original. El servidor SQL no puede garantizar el orden de las filas si no especifica ORDER BY. Puede tener suerte y obtener resultados en un orden particular, pero puede cambiar en cualquier momento.

6

El problema real con el enfoque que está proponiendo es que el orden en el archivo db no está garantizado. Es posible que, por coincidencia, regrese a su aplicación en el mismo orden todo el tiempo, pero el estándar SQL no garantiza dicho orden y puede cambiar según la versión o los cambios de edición. El orden de los datos de un SQL Server no está garantizado sin una cláusula order by. Este diseño sería uno que simplemente se basa en la "suerte". Si esta posible variación en el orden tiene un impacto en su implementación, es posible que desee cambiarla ahora antes de llegar demasiado lejos en la implementación.

Good article on this topic

+0

@Legend: Agregué un enlace a un artículo que trata el tema del ordenamiento de conjuntos de resultados de SQL Server. –

20

Lo utilizo para suprimir la especie:

ORDER BY @@rowcount 

@@ recuento de filas es constante dentro de la consulta. Ejemplo:

select N = row_number() over (order by @@rowcount) from sys.columns 

El uso de (seleccionar 0) en ORDER BY parece ser mucho más lento.

1

Hay una solución que es más simple que la anterior. Puede seguir utilizando ROW_NUMBER pero suministrar un valor arbitrario en la cláusula ORDER BY:

Select firstName, lastName, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) from tblPerson 
Cuestiones relacionadas