Question

Dans PostgreSQL il y a les mots-clés Limit et Offset qui permettront très facile de pagination jeux de résultats.

Quelle est la syntaxe équivalente pour Sql Server?

Était-ce utile?

La solution

L'équivalent de LIMIT est SET ROWCOUNT, mais si vous voulez générique, il est pagination préférable d'écrire une requête comme ceci:

;WITH Results_CTE AS
(
    SELECT
        Col1, Col2, ...,
        ROW_NUMBER() OVER (ORDER BY SortCol1, SortCol2, ...) AS RowNum
    FROM Table
    WHERE <whatever>
)
SELECT *
FROM Results_CTE
WHERE RowNum >= @Offset
AND RowNum < @Offset + @Limit

L'avantage ici est le paramétrage du décalage et limite au cas où vous décidez de modifier vos options de pagination (ou permettre à l'utilisateur de le faire).

Remarque: le paramètre @Offset doit utiliser l'indexation à base d'un pour cela plutôt que de l'indexation de base zéro normal.

Autres conseils

Cette fonctionnalité est maintenant facile dans SQL Server 2012. Cela fonctionne à partir de SQL Server 2012.

Limite de décalage pour sélectionner 11 à 20 lignes dans SQL Server:

SELECT email FROM emailTable 
WHERE user_id=3
ORDER BY Id
OFFSET 10 ROWS
FETCH NEXT 10 ROWS ONLY;
  • OFFSET: nombre de lignes sautées
  • NEXT: nombre requis de lignes suivantes

Référence: https://docs.microsoft.com/en-us/sql/t-sql/queries/select-order-by-clause-transact-sql?view=sql-server-2017

select top {LIMIT HERE} * from (
      select *, ROW_NUMBER() over (order by {ORDER FIELD}) as r_n_n 
      from {YOUR TABLES} where {OTHER OPTIONAL FILTERS}
) xx where r_n_n >={OFFSET HERE}

Une note: Cette solution ne fonctionne que dans SQL Server 2005 ou au-dessus, étant donné que ce fut quand ROW_NUMBER() a été mis en œuvre.

Vous pouvez utiliser ROW_NUMBER dans une expression de table commune pour y parvenir.

;WITH My_CTE AS
(
     SELECT
          col1,
          col2,
          ROW_NUMBER() OVER(ORDER BY col1) AS row_number
     FROM
          My_Table
     WHERE
          <<<whatever>>>
)
SELECT
     col1,
     col2
FROM
     My_CTE
WHERE
     row_number BETWEEN @start_row AND @end_row

Pour moi, l'utilisation de OFFSET et FETCH ensemble était lent, donc j'ai utilisé une combinaison de TOP et OFFSET comme celui-ci (ce qui était plus rapide):

SELECT TOP 20 * FROM (SELECT columname1, columname2 FROM tablename
    WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS) aliasname

Remarque: Si vous utilisez TOP et OFFSET ensemble dans la même requête comme:

SELECT TOP 20 columname1, columname2 FROM tablename
    WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS

Ensuite, vous obtenez une erreur, donc pour TOP et OFFSET ensemble, vous devez séparer avec une sous-requête.

Et si vous avez besoin d'utiliser SELECT DISTINCT alors la requête est comme:

SELECT TOP 20 FROM (SELECT DISTINCT columname1, columname2
    WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS) aliasname

Remarque:. L'utilisation de SELECT ROW_NUMBER Distinct ne fonctionne pas pour moi

Un autre exemple:

declare @limit int 
declare @offset int 
set @offset = 2;
set @limit = 20;
declare @count int
declare @idxini int 
declare @idxfim int 
select @idxfim = @offset * @limit
select @idxini = @idxfim - (@limit-1);
WITH paging AS
    (
        SELECT 
             ROW_NUMBER() OVER (order by object_id) AS rowid, *
        FROM 
            sys.objects 
    )
select *
    from 
        (select COUNT(1) as rowqtd from paging) qtd, 
            paging 
    where 
        rowid between @idxini and @idxfim
    order by 
        rowid;

Il est quelqu'un dire sur cette fonctionnalité dans sql 2011, sa triste qu'ils choisissent un peu différent mot-clé « OFFSET / fetch », mais ce ne est pas standart alors ok.

Ajout d'une légère variation sur la solution de Aaronaught, je généralement le numéro de page Paramétrer (@PageNum) et la taille de la page (@PageSize). De cette façon, chaque événement click page envoie juste le numéro de page demandée avec une taille de page configurable:

begin
    with My_CTE  as
    (
         SELECT col1,
              ROW_NUMBER() OVER(ORDER BY col1) AS row_number
     FROM
          My_Table
     WHERE
          <<<whatever>>>
    )
    select * from My_CTE
            WHERE RowNum BETWEEN (@PageNum - 1) * (@PageSize + 1) 
                              AND @PageNum * @PageSize

end

Le plus proche que je pourrais faire est

select * FROM( SELECT *, ROW_NUMBER() over (ORDER BY ID ) as ct from [db].[dbo].[table] ) sub where ct > fromNumber  and ct <= toNumber

Ce que je pense similaire à select * from [db].[dbo].[table] LIMIT 0, 10

select top (@TakeCount) * --FETCH NEXT
from(
    Select  ROW_NUMBER() OVER (order by StartDate) AS rowid,*
    From YourTable
)A
where Rowid>@SkipCount --OFFSET
@nombre_row :nombre ligne par page  
@page:numero de la page

//--------------code sql---------------

declare  @page int,@nombre_row int;
    set @page='2';
    set @nombre_row=5;
    SELECT  *
FROM    ( SELECT    ROW_NUMBER() OVER ( ORDER BY etudiant_ID ) AS RowNum, *
      FROM      etudiant

    ) AS RowConstrainedResult
WHERE   RowNum >= ((@page-1)*@nombre_row)+1
    AND RowNum < ((@page)*@nombre_row)+1
ORDER BY RowNum

Comme personne encore fourni ce code:

SELECT TOP @limit f1, f2, f3...
FROM t1
WHERE c1 = v1, c2 > v2...
AND
    t1.id NOT IN
        (SELECT TOP @offset id
         FROM t1
         WHERE c1 = v1, c2 > v2...
         ORDER BY o1, o2...)
ORDER BY o1, o2...

Points importants:

  • ORDER BY doit être identique
  • @limit peut être remplacé par nombre de résultats pour récupérer,
  • @offset est le nombre de résultats pour sauter
  • S'il vous plaît comparer les performances des solutions précédentes, car ils peuvent être plus efficaces
  • cette solution fait double emploi avec des clauses de where et order by, et fournira des résultats incorrects si elles ne sont pas synchronisés
  • d'autre part order by est là explicitement si c'est ce qui est nécessaire
-- @RowsPerPage  can be a fixed number and @PageNumber number can be passed 
DECLARE @RowsPerPage INT = 10, @PageNumber INT = 2

SELECT *

FROM MemberEmployeeData

ORDER BY EmployeeNumber

OFFSET @PageNumber*@RowsPerPage ROWS

FETCH NEXT 10 ROWS ONLY

Dans le serveur SQL que vous utilisez TOP avec ROW_NUMBER ()

SELECT * FROM [dbo].[TableName] Order By  [dbo].[TableName].FieldName DESC
OFFSET 10 ROWS
FETCH NEXT 10 ROWS ONLY
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top