Dans PostgreSQL, il y a les mots-clés Limit
et Offset
qui permettent une pagination très facile des ensembles de résultats.Équivalent de LIMIT et OFFSET pour SQL Server?
Quelle est la syntaxe équivalente pour Sql Server?
Dans PostgreSQL, il y a les mots-clés Limit
et Offset
qui permettent une pagination très facile des ensembles de résultats.Équivalent de LIMIT et OFFSET pour SQL Server?
Quelle est la syntaxe équivalente pour Sql Server?
L'équivalent de LIMIT
est SET ROWCOUNT
, mais si vous voulez la pagination générique, il est 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 changer vos options de pagination (ou permettre à l'utilisateur de le faire).
Remarque: le paramètre doit utiliser l'indexation basée sur un seul pour cela plutôt que l'indexation normale basée sur zéro.
Ancien maintenant Sql Server 2012 et versions ultérieures prennent en charge OFFSET/FETCH –
@JoelCoehoorn Pas vieux, je viens d'être assigné au projet en utilisant SLQ Server 2008 ayant utilisé seulement mysql dans le passé ... – Cthulhu
Ceci est assez bon mais doit être ajusté un peu 'WHERE RowNum> = (@Offset + 1 '' –
Dans le serveur SQL que vous utilisez TOP avec ROW_NUMBER()
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
Cela aurait dû être la réponse acceptée.Parfait –
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;
J'ai supprimé votre discours de haine anti-microsoft. Ne discutez pas des guerres saintes ici; Il suffit de répondre et de poser des questions de manière non subjective. – Earlz
Il y a here quelqu'un dire sur cette fonctionnalité dans sql 2011, sa triste qu'ils choisissent un petit mot clé différent "OFFSET/fetch", mais ce ne est pas standart alors ok.
Cette fonctionnalité est désormais simplifiée dans SQL Server 2012. Cela fonctionne mais SQL server 2012 et après. Limite avec un décalage pour sélectionner 11 à 20 lignes dans le serveur sql:
SELECT email FROM emailTable
WHERE id=3
ORDER BY Id
OFFSET 10 ROWS
FETCH NEXT 10 ROWS ONLY;
// offset - pas. de lignes sautées
// suivant - N ° requis des lignes suivantes
En ajoutant une légère variation à la solution d'Aaronaught, je paramétrise généralement le numéro de page (@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
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 fonctionnera que dans SQL Server 2005 ou au-dessus, étant donné que cette était lorsque ROW_NUMBER()
a été mis en œuvre.
J'utilise cette requête depuis un petit moment maintenant et ça marche très bien alors merci pour ça. Je me demande juste ce que le "xx" représente? – Urbley
la sous-requête nécessite un nom. comme je ne l'utilise pas il suffit de mettre xx là – jorgeu
Le xx est juste un alias de table. Il pourrait être un peu plus clair si vous avez dit 'AS xx' –
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
cela fonctionne merci. – oguzhan
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
Puisque personne a fourni ce code encore:
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:
@limit
peut être remplacé par nombre de résultats à récupérer,@offset
est le nombre de résultats pour sauterwhere
et order by
, et fournira des résultats incorrects s'ils ne sont pas synchronisésorder by
est là explicitement si c'est ce qui est nécessairePour 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
note: 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 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
Note: L'utilisation de SELECT ROW_NUMBER Distinct ne fonctionne pas pour moi.
Je reçois "Un TOP ne peut pas être utilisé dans la même requête ou sous-requête qu'un OFFSET." – MichaelRushton
Vous avez raison @MichaelRushton, ne peut pas être utilisé dans la même requête ou dans la même sous-requête, alors vous devez utiliser une sous-requête pour le séparer. Donc si vous avez le SQL comme 'SELECT TOP 20 id FROM table1 où id> 10 ordre par date OFFSET 20 rows', vous devez le transformer comme' SELECT TOP 20 * FROM (SELECT ID FROM table1 où id> 10 ordre par date OFFSET 20 RANGÉES) t1'. Je vais éditer ma réponse. Merci et excusez-moi mon anglais. – sebasdev
-- @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
Pour SQL Server 2012, cette fonctionnalité est implémentée de manière simple. Voir [ma réponse] (http://stackoverflow.com/a/9261762/1045444) –
Merci d'avoir posé cette question, nous sommes obligés de faire la transition de MySQL à MsSQL :( – Logikos