J'essaie de faire quelque chose comme:
SELECT * FROM table LIMIT 10,20
ou
SELECT * FROM table LIMIT 10 OFFSET 10
mais en utilisant SQL Server
Le seul solution que j'ai trouvée ressemble à un excès:
SELECT * FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY name) as row FROM sys.databases
) a WHERE row > 5 and row <= 10
J'ai aussi trouvé :
SELECT TOP 10 * FROM stuff;
... mais ce n'est pas ce que je veux faire car je ne peux pas spécifier la limite de départ.
Y a-t-il un autre moyen pour moi de faire cela?
Aussi, juste curieux, y a-t-il une raison pour laquelle SQL Server ne prend pas en charge la fonction LIMIT
ou quelque chose de similaire? Je ne veux pas être méchant, mais cela ressemble vraiment à quelque chose dont un SGBD a besoin ... Si c'est le cas, je suis désolé d'être aussi ignorant! Je travaille avec MySQL et SQL + depuis 5 ans, alors ...
La clause LIMIT
ne fait pas partie du SQL standard. Il est supporté comme extension de fournisseur à SQL par MySQL, PostgreSQL et SQLite.
D'autres marques de base de données peuvent avoir des fonctionnalités similaires (par exemple, TOP
dans Microsoft SQL Server), mais celles-ci ne fonctionnent pas toujours de manière identique.
Il est difficile d'utiliser TOP
dans Microsoft SQL Server pour imiter la clause LIMIT
. Il y a des cas où cela ne fonctionne tout simplement pas.
La solution que vous avez présentée à l’aide de ROW_NUMBER()
est disponible dans Microsoft SQL Server 2005 et versions ultérieures. C'est la meilleure solution (pour l'instant) qui fonctionne uniquement dans le cadre de la requête.
Une autre solution consiste à utiliser TOP
pour extraire le premier nombre + offset lignes, puis utilisez l’API pour rechercher au-delà des premières décalées lignes.
Voir également:
Pour SQL Server 2012 + vous pouvez utiliser .
SELECT *
FROM sys.databases
ORDER BY name
OFFSET 5 ROWS
FETCH NEXT 5 ROWS ONLY
comme vous l'avez constaté, il s'agit de la méthode de serveur SQL préférée:
SELECT * FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY name) as row FROM sys.databases
) a WHERE a.row > 5 and a.row <= 10
Si vous utilisez SQL Server 2012+, votez pour réponse de Martin Smith et utilisez les extensions OFFSET
et FETCH NEXT
de ORDER BY
,
Si vous êtes assez malheureux pour vous retrouver avec une version antérieure, vous pouvez faire quelque chose comme ça,
WITH Rows AS
(
SELECT
ROW_NUMBER() OVER (ORDER BY [dbo].[SomeColumn]) [Row]
, *
FROM
[dbo].[SomeTable]
)
SELECT TOP 10
*
FROM
Rows
WHERE Row > 10
Je crois est fonctionnellement équivalent à
SELECT * FROM SomeTable LIMIT 10 OFFSET 10 ORDER BY SomeColumn
et le moyen le plus performant que je connaisse de le faire dans TSQL, avant MS SQL 2012.
S'il y a beaucoup de lignes, vous obtiendrez de meilleures performances en utilisant une table temporaire au lieu d'un CTE.
Malheureusement, la ROW_NUMBER()
est ce que vous pouvez faire de mieux. C'est en fait plus correct, car les résultats d'une clause limit
ou top
n'ont pas vraiment de sens sans respecter un ordre spécifique. Mais c'est toujours pénible à faire.
Mise à jour: Sql Server 2012 ajoute une fonctionnalité de type limit
via mots-clés OFFSET et FETCH . C'est l'approche ansi-standard, par opposition à LIMIT
, qui est une extension MySql non standard.
Que dis-tu de ça?
SET ROWCOUNT 10
SELECT TOP 20 *
FROM sys.databases
ORDER BY database_id DESC
Il vous donne les 10 dernières lignes des 20 premières lignes. Un inconvénient est que l'ordre est inversé, mais au moins, il est facile de s'en souvenir.
SELECT TOP 10 *
FROM TABLE
WHERE IDCOLUMN NOT IN (SELECT TOP 10 IDCOLUMN FROM TABLE)
Devrait donner des enregistrements 11-20. Probablement pas trop efficace si incrémenté pour obtenir des pages supplémentaires, et pas sûr de savoir comment cela pourrait être affecté par la commande. Vous devrez peut-être spécifier cela dans les deux instructions WHERE.
Juste pour la solution d'enregistrement qui fonctionne sur la plupart des moteurs de base de données, elle pourrait ne pas être la plus efficace:
Select Top (ReturnCount) *
From (
Select Top (SkipCount + ReturnCount) *
From SourceTable
Order By ReverseSortCondition
) ReverseSorted
Order By SortCondition
Note Pelase: la dernière page contiendrait toujours des lignes ReturnCount, quel que soit SkipCount. Mais cela pourrait être une bonne chose dans de nombreux cas.
Un bon moyen est de créer une procédure:
create proc pagination (@startfrom int ,@endto int) as
SELECT * FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY name desc) as row FROM sys.databases
) a WHERE a.row > @startfrom and a.row <= @endto
comme limite 0,2 /////////////// exécuter la pagination 0,4
L'équivalent de LIMIT est 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
Utilisez tous les serveurs SQL:; avec tbl comme (SELECT ROW_NUMBER () sur (ordre de (sélectionnez 1)) comme RowIndex, * du tableau), sélectionnez Top 10 * à partir de tbl où RowIndex> = 10
Dans la documentation en ligne de MS SQL Server ( http://technet.Microsoft.com/en-us/library/ms186734.aspx ), voici l’exemple que j’ai testé et qui fonctionne pour récupérer une ensemble spécifique de lignes. ROW_NUMBER nécessite un OVER, mais vous pouvez commander ce que vous voulez:
WITH OrderedOrders AS
(
SELECT SalesOrderID, OrderDate,
ROW_NUMBER() OVER (ORDER BY OrderDate) AS RowNumber
FROM Sales.SalesOrderHeader
)
SELECT SalesOrderID, OrderDate, RowNumber
FROM OrderedOrders
WHERE RowNumber BETWEEN 50 AND 60;
Jusqu'à présent, ce format est ce qui fonctionne pour moi (pas la meilleure performance cependant):
SELECT TOP {desired amount of rows} *
FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY {order columns} asc)__row__ FROM {table})tmp
WHERE __row__ > {offset row count}
Une note sur le côté, paginant sur des données dynamiques peut conduire à des résultats étranges/inattendus.
select * from (select id,name,ROW_NUMBER() OVER (ORDER BY id asc) as row
from tableName1) tbl1
where tbl1.row>=10 and tbl1.row<=15
Imprimera les lignes de 10 à 15.