2009-09-25 14 views
7

Con la esperanza de que esto es trivial para un SQL-Ninja ... estado tratando de conseguir el siguiente trabajo de consulta:usar el ordenamiento de funciones columna derivada en la cláusula WHERE (SQL Server 2008)

Esto es para SQL Server 2008

SELECT 
    ROW_NUMBER() OVER (ORDER BY Date_Time DESC) AS RowNumber, * 
FROM 
    (SELECT 
     T.A_ID, T.User_Name, T.Date_Time, T.Value, 
     U.ID, U.Name, U.Field1, U.Field2, 
     COUNT(U.ID) OVER() AS TotalRows 
    FROM 
     TeeTable as T 
    INNER JOIN 
     YouTable AS U ON T.U_ID = U.ID 
    WHERE 
     T.Value BETWEEN 222 AND 225) Filtered 
WHERE 
    RowNumber BETWEEN 1 AND 5 

Los valores se idearon de alguna manera para dar un ejemplo específico, pero el espíritu de la consulta se conserva por completo. El error que obtengo de esta declaración es:

Nombre de la columna no válida 'RowNumber'.

Si quito la final cláusula WHERE (RowNumber ENTRE ...) que devuelve un conjunto de resultados esperados (A_ID, Nombre_usuario, Date_Time etc ...), con RowNumber como una columna (con valores sensical) en dicha resultados. Sin embargo, no puedo compararlo en la cláusula WHERE. Claramente estoy haciendo algo estúpido, pero esto llega a mi límite de SQL.

He intentado reordenar esto también como CTE, (CON FILTRADO COMO ...) pero el resultado final es el mismo, parece que es solo un azúcar para lo que ya estoy haciendo.

Ideas? ¿Cómo puedo filtrar contra la columna derivada RowNumber?

+0

Evita la etiqueta 'mssql' ya que se confunde fácilmente con' mysql' –

Respuesta

15

Debe mover el operador WHERE anterior a la lista de proyectos donde se crea la columna RowNumber. Utilizar una tabla derivada o un CTE:

SELECT * 
    FROM (
    SELECT *, ROW_NUMBER() OVER (...) as RowNumber 
    FROM ...) As ... 
WHERE RowNumber = ... 

el CTE equivalente es:

WITH cte AS (
SELECT *, ROW_NUMBER() OVER (...) as RowNumber 
     FROM ...) 
SELECT * FROM cte 
WHERE RowNumber = ... 
+0

¡Funcionó muy bien, gracias! –

3

Las funciones de la ventana (de los cuales ROW_NUMBER es la mejor conoce) está lleno de muy tarde en la consulta, bien después de la cláusula WHERE. Por lo tanto usted tiene que anidan también que, con el fin de filtrar en él:

SELECT * 
FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY Date_Time DESC) AS RowNumber, * 
    FROM 
    (SELECT T.A_ID, T.User_Name, T.Date_Time, T.Value, 
      U.ID, U.Name, U.Field1, U.Field2, 
      COUNT(U.ID) OVER() AS TotalRows 
     FROM 
     TeeTable as T INNER JOIN YouTable AS U 
     ON T.U_ID = U.ID 
     WHERE T.Value BETWEEN 222 AND 225 
    ) Numbered 
) Filtered 
WHERE RowNumber BETWEEN 1 AND 5 

También ellos se pueden poner en CTE o lo considere para obtener el mismo efecto.

+0

No puedo aceptar 2 respuestas, pero te devolveré el voto. :) ¡Gracias! –

0

El problema con la consulta entra debido a la falla en el orden de procesamiento lógico. Este es el orden de procesamiento lógico especificado en MSDN dev Network.

Procesamiento lógico Orden de la instrucción SELECT Los siguientes pasos muestran el orden lógico de procesamiento u orden de enlace para una instrucción SELECT. Este orden determina cuándo los objetos definidos en un paso están disponibles para las cláusulas en los pasos posteriores. Por ejemplo, si el procesador de consultas puede enlazar (acceder) a las tablas o vistas definidas en la cláusula FROM, estos objetos y sus columnas estarán disponibles para todos los pasos subsiguientes. Por el contrario, dado que la cláusula SELECT es el paso 8, los alias de columna o las columnas derivadas definidas en esa cláusula no pueden ser referenciadas por las cláusulas precedentes. Sin embargo, pueden ser referenciados por cláusulas posteriores como la cláusula ORDER BY. Tenga en cuenta que la ejecución física real de la declaración está determinada por el procesador de consultas y el orden puede variar de esta lista. DE EN ÚNETE DONDE GROUP BY CON EL CUBO o WITH ROLLUP TIENE SELECT DISTINCT ORDER BY TOP

Así introducir la función de clasificación como un alias en la subconsulta en la sección y entonces podrá establecer una condición en el alias en la sección donde.

¡Buena suerte .. !!

Cuestiones relacionadas