Dans PostgreSQL, il existe les mots Limit- Offsetclés et qui permettront une pagination très simple des ensembles de résultats.
Quelle est la syntaxe équivalente pour SQL Server?
Dans PostgreSQL, il existe les mots Limit- Offsetclés et qui permettront une pagination très simple des ensembles de résultats.
Quelle est la syntaxe équivalente pour SQL Server?
Réponses:
L'équivalent de LIMITis SET ROWCOUNT, mais si vous voulez une pagination générique, il est préférable d'écrire une requête comme celle-ci:
;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 de l'offset et de la limite au cas où vous décideriez de modifier vos options de pagination (ou autoriser l'utilisateur à le faire).
Remarque: le @Offsetparamètre doit utiliser pour cela l'indexation basée sur un plutôt que l'indexation de base zéro normale.
WHERE RowNum >= (@Offset + 1)
The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP or FOR XML is also specified. MSSQL2008 R2.
Tablea 200k enregistrements, il va tout d'abord récupérer, puis appliquer la limite? Cette requête est-elle efficace?
Cette fonctionnalité est désormais simplifiée dans SQL Server 2012. Cela fonctionne à partir de SQL Server 2012.
Limiter avec 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 ignoréesNEXT: nombre requis de lignes suivantesSQL_CALC_FOUND_ROWSlors de son utilisation?
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}
Remarque:
cette solution ne fonctionnera que dans SQL Server 2005 ou supérieur, car c'était à ce moment-là qu'elle a ROW_NUMBER()été implémentée.
AS xx
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 lente, j'ai donc utilisé une combinaison de TOP et OFFSET comme celle-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 utiliser TOP et OFFSET ensemble, vous devez le séparer avec une sous-requête.
Et si vous devez utiliser SELECT DISTINCT, 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 avec DISTINCT n'a pas fonctionné pour moi.
SELECT TOP 20 id FROM table1 where id > 10 order by date OFFSET 20 rows, vous devez le transformer comme SELECT TOP 20 * FROM (SELECT id FROM table1 where id > 10 order by date OFFSET 20 ROWS) t1. Je modifierai ma réponse. Merci et excusez-moi mon anglais.
Un autre échantillon:
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 y a ici quelqu'un qui parle de cette fonctionnalité dans sql 2011, c'est triste qu'ils choisissent un mot-clé un peu différent "OFFSET / FETCH" mais ce n'est pas standart alors ok.
En ajoutant une légère variation à la solution d'Aaronaught, je paramètre généralement le numéro de page (@PageNum) et la taille de la page (@PageSize). De cette façon, chaque événement de clic de page envoie simplement le numéro de page demandé 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 qui je suppose similaire à select * from [db].[dbo].[table] LIMIT 0, 10
-- @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
@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
Puisque personne n'a 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...
Les points importants:
@limit peut être remplacé par le nombre de résultats à récupérer,@offset est le nombre de résultats à ignorerwhereet order byclause, et fournira des résultats incorrects s'ils ne sont pas synchronisésorder byest-il explicitement si c'est ce qu'il fautEn particulier pour SQL-SERVER, vous pouvez y parvenir de différentes manières. Pour un exemple concret, nous avons pris la table Customer ici.
Exemple 1: avec "SET ROWCOUNT"
SET ROWCOUNT 10
SELECT CustomerID, CompanyName from Customers
ORDER BY CompanyName
Pour renvoyer toutes les lignes, définissez ROWCOUNT sur 0
SET ROWCOUNT 0
SELECT CustomerID, CompanyName from Customers
ORDER BY CompanyName
Exemple 2: avec "ROW_NUMBER et OVER"
With Cust AS
( SELECT CustomerID, CompanyName,
ROW_NUMBER() OVER (order by CompanyName) as RowNumber
FROM Customers )
select *
from Cust
Where RowNumber Between 0 and 10
Exemple 3: Avec "OFFSET et FETCH", mais avec ce "ORDER BY" est obligatoire
SELECT CustomerID, CompanyName FROM Customers
ORDER BY CompanyName
OFFSET 0 ROWS
FETCH NEXT 10 ROWS ONLY
J'espère que cela vous aide.
Depuis, je teste plus de fois ce script plus utile de 1 million d'enregistrements chaque page 100 enregistrements avec pagination fonctionnent plus rapidement mon PC exécute ce script 0 sec alors que le comparatif avec mysql a sa propre limite et un décalage d'environ 4,5 sec pour obtenir le résultat.
Quelqu'un peut manquer de comprendre Row_Number () trier toujours par champ spécifique. Au cas où nous aurions besoin de définir uniquement la ligne dans la séquence, utilisez:
SELECT TOP {LIMIT} * FROM (
SELECT TOP {LIMIT} + {OFFSET} ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS ROW_NO,*
FROM {TABLE_NAME}
) XX WHERE ROW_NO > {OFFSET}
Explique: