2009-11-26 9 views
22

J'utilise une expression de table commune pour la pagination:Comment puis-je réutiliser une expression de table commune

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 

Immédiatement après avoir fait cette requête, je fais faire une requête presque identique afin de récupérer le nombre total d'éléments :

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

J'ai essayé la combinaison de ces ensemble (à savoir: définir le CTE, interroger les données, puis interroger le comte, mais quand je le fais, je reçois un message d'erreur « nom d'objet incorrect" requête » dans réponse la deuxième requête (le nombre)

Est-il possible de combiner ces deux requêtes en une seule, pour enregistrer un aller-retour dans la base de données?

Répondre

33

Si vous ne désirez pas 2 différentes requêtes, vous pouvez essayer

;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 vous ne souhaitez 2 différentes requêtes, utilisez plutôt une table 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

Quel est le point d'utiliser un CTE ici? –

+2

@ Scott Rippey, je trouve que les CTE peuvent lire, réutiliser et maintenir. –

+0

Oh merci. Dans votre premier bloc de code, vous utilisez un CTE pour obtenir le total et obtenir les résultats, ce qui est parfaitement logique. Mais j'obtiens une erreur lorsque j'essaie d'interroger un CTE deux fois. Pouvez-vous expliquer pourquoi cela fonctionne? –

2

Vous pouvez le faire comme ceci:

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 vous ajoutez 4 espaces avant les lignes de code, il est reconnu comme code par débordement de pile. – Gamlor

+0

Parfois, la requête elle-même peut avoir des fonctions agrégées (FirstName, LastName était juste un exemple simple), donc ajouter Count (*) comme une colonne ne serait pas une solution fiable. –

2

Selon Microsoft dans ce link:

A CTE peut se référencer et CTE défini précédemment dans la même AVEC clause.

Dans ce nouveau CTE faisant référence à la CTE défini précédente, nous pouvons faire la requête de comptage:

;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 

« query » est le CTE principal et « totalCount » utilise pour obtenir les lignes au total comptent

Microsoft devrait avoir un exemple pour une tâche commune comme celle-ci.

Questions connexes