2009-11-26 13 views
22

Estoy utilizando una expresión de tabla común para paginación:¿Cómo puedo volver a usar una expresión de tabla común

with query as (
    Select Row_Number() over (Order By OrderNum ASC) as TableRowNum, 
     FirstName, 
     LastName 
    From Users 
) 
Select * from query where TableRowNum between 1 and 25 Order By TableRowNum ASC 

Inmediatamente después de hacer esta consulta, hago hacer una consulta casi idéntico con el fin de recuperar el número total de elementos :

with query as (
    Select Row_Number() over (Order By OrderNum ASC) as TableRowNum, 
     FirstName, 
     LastName 
    From Users 
) 
Select Count(*) from query 

he intentado combinar estos juntos (es decir: definir el CTE, consultar los datos y luego consultar la cuenta, pero cuando hago esto, me sale un mensaje de error "nombre de objeto no válido 'consulta'" en responda la segunda consulta (el recuento).

¿Hay alguna forma de combinar estas dos consultas en una, para guardar un viaje de ida y vuelta a la base de datos?

Respuesta

33

Si no se requiere en 2 consultas diferentes, puede intentar

;with query as (
    Select Row_Number() over (Order By UserID ASC) as TableRowNum, 
     FirstName, 
     LastName 
    From Users 
), 
totalCount AS (
    SELECT COUNT(1) Total FROM query 
) 
Select query.*, 
     Total 
from query, totalCount 
where TableRowNum 
between 1 and 25 
Order By TableRowNum ASC 

Si necesita 2 consultas diferentes, en lugar utilizar una tabla var

DECLARE @User TABLE(
     TableRowNum INT, 
     FirstName VARCHAR(50), 
     LastName VARCHAR(50) 
) 
;with query as (
    Select Row_Number() over (Order By UserID ASC) as TableRowNum, 
     FirstName, 
     LastName 
    From Users 
) 
INSERT INTO @User 
SELECT TableRowNum, 
     FirstName, 
     LastName 
FROM query 

SELECT * 
FROM @User 
where TableRowNum 
between 1 and 25 
Order By TableRowNum ASC 

SELECT COUNT(1) FROM @User 
+0

¿Cuál es el punto de usar un CTE aquí? –

+2

@Scott Rippey, encuentro CTEs eaiser para leer, reutilizar y mantener. –

+0

Oh gracias. En su primer bloque de código, utiliza un CTE para obtener el total y obtener los resultados, lo que tiene mucho sentido. Pero recibo un error cuando intento consultar un CTE dos veces. ¿Puedes explicar por qué esto funciona? –

2

Usted puede hacer eso de esta manera:

with query as (
    Select 
COUNT (*) OVER (PARTITION BY 1) AS TableTotalRows, 
Row_Number() over (Order By OrderNum ASC) as TableRowNum, 
    FirstName, 
    LastName 
    From Users 
) 
+0

si agrega 4 espacios antes de las líneas de código, se reconoce como código por desbordamiento de pila. – Gamlor

+0

A veces, la consulta en sí puede tener funciones agregadas (FirstName, LastName era solo un ejemplo), por lo que agregar 'Count (*)' como columna no sería una solución confiable. –

2

de acuerdo con Microsoft en este link:

A CTE puede hacer referencia a sí mismo y CTEs previamente definido en el mismo CON cláusula.

En ese nuevo CTE hace referencia a la anterior define CTE, podemos hacer la consulta recuento:

;with query as (
    Select Row_Number() over (Order By UserID ASC) as TableRowNum, 
     FirstName, 
     LastName 
    From Users 
), 
totalCount AS (
    SELECT COUNT(1) Total FROM query 
) 
Select query.*, 
     Total 
from query, totalCount 
where TableRowNum 
between 1 and 25 
Order By TableRowNum ASC 

'consulta' es el principal CTE y 'totalCount' lo está utilizando para obtener el recuento de filas totales

Microsoft debería tener un ejemplo para una tarea común como esta.

Cuestiones relacionadas