Implémenter la fonctionnalité de pagination (sauter / prendre) avec cette requête


138

J'ai essayé de comprendre un peu comment implémenter la pagination personnalisée dans SQL, par exemple en lisant des articles comme celui-ci .

J'ai la requête suivante, qui fonctionne parfaitement. Mais je voudrais implémenter la pagination avec celui-ci.

SELECT TOP x PostId FROM ( SELECT PostId, MAX (Datemade) as LastDate
 from dbForumEntry 
 group by PostId ) SubQueryAlias
 order by LastDate desc

Qu'est-ce que je veux

J'ai des messages sur le forum, avec des entrées connexes. Je veux obtenir les messages avec les dernières entrées ajoutées, afin de pouvoir sélectionner les messages récemment débattus.

Maintenant, je veux pouvoir obtenir le "top 10 à 20 articles récemment actifs", au lieu du "top 10".

Qu'ai-je essayé

J'ai essayé d'implémenter les fonctions ROW comme celle de l'article, mais vraiment sans succès.

Des idées comment le mettre en œuvre?

Réponses:


288

Dans SQL Server 2012, c'est très très simple

SELECT col1, col2, ...
 FROM ...
 WHERE ... 
 ORDER BY -- this is a MUST there must be ORDER BY statement
-- the paging comes here
OFFSET     10 ROWS       -- skip 10 rows
FETCH NEXT 10 ROWS ONLY; -- take 10 rows

Si nous voulons sauter ORDER BY, nous pouvons utiliser

SELECT col1, col2, ...
  ...
 ORDER BY CURRENT_TIMESTAMP
OFFSET     10 ROWS       -- skip 10 rows
FETCH NEXT 10 ROWS ONLY; -- take 10 rows

(Je préfère marquer cela comme un hack - mais il est utilisé, par exemple par NHibernate. Utiliser une colonne judicieusement choisie comme ORDER BY est la méthode préférée)

pour répondre à la question:

--SQL SERVER 2012
SELECT PostId FROM 
        ( SELECT PostId, MAX (Datemade) as LastDate
            from dbForumEntry 
            group by PostId 
        ) SubQueryAlias
 order by LastDate desc
OFFSET 10 ROWS -- skip 10 rows
FETCH NEXT 10 ROWS ONLY; -- take 10 rows

De nouveaux mots clés offsetet fetch next(juste en suivant les normes SQL) ont été introduits.

Mais je suppose que vous n'utilisez pas SQL Server 2012 , non ? Dans la version précédente, c'est un peu (un peu) difficile. Voici une comparaison et des exemples pour toutes les versions de serveur SQL: ici

Donc, cela pourrait fonctionner dans SQL Server 2008 :

-- SQL SERVER 2008
DECLARE @Start INT
DECLARE @End INT
SELECT @Start = 10,@End = 20;


;WITH PostCTE AS 
 ( SELECT PostId, MAX (Datemade) as LastDate
   ,ROW_NUMBER() OVER (ORDER BY PostId) AS RowNumber
   from dbForumEntry 
   group by PostId 
 )
SELECT PostId, LastDate
FROM PostCTE
WHERE RowNumber > @Start AND RowNumber <= @End
ORDER BY PostId

Merci beaucoup! C'est une très bonne réponse! Seule question sur le sql 2008. Je veux que ORDER BY se produise avant le WHERE, car il triera actuellement le sous-ensemble, mais nous voulons sélectionner quelque chose dans l'ensemble ... Des idées? :) Encore une fois, merci
Lars Holdgaard

2
Si je vous comprends bien, vous aimeriez trier par LastDate, non? alors nous pouvons changer la clause OVER () de cette façon: ROW_NUMBER () OVER (ORDER BY MAX (Datemade) desc ). Et supprimez le dernier ORDER BY PostId . Maintenant, le CTE devrait être trié «plus tôt» selon les besoins. correct?
Radim Köhler

1
Merci pour cette aide, une note sur l'échantillon 2012, commander par est obligatoire, j'essayais ceci sans ordre par clause et j'ai eu l'erreur "syntaxe incorrecte" je n'avais aucune idée de ce qui n'allait pas jusqu'à ce que je regarde dans la syntaxe MSDN et que j'apprenne que la commande par est obligatoire .
Esen

La première ligne est-elle 1 ou 0? Le WHERE devrait-il être WHERE RowNumber >= @Start AND RowNumber < @Endpour obtenir les 1000 premières lignes si @Startest 0 et @End1000?
CWSpear

1
Merci beaucoup
Mafii



5

SQL 2008

La réponse de Radim Köhler fonctionne, mais voici une version plus courte:

select top 20 * from
(
select *,
ROW_NUMBER() OVER (ORDER BY columnid) AS ROW_NUM
from tablename
) x
where ROW_NUM>10

Source: https://forums.asp.net/post/4033909.aspx


-1

Vous pouvez utiliser une requête imbriquée pour la pagination comme suit:

Pagination de 4 lignes à 8 lignes où CustomerId est la clé primaire .

SELECT Top 5 * FROM Customers
WHERE Country='Germany' AND CustomerId Not in (SELECT Top 3 CustomerID FROM Customers
WHERE Country='Germany' order by city) 
order by city;
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.