Je cherche une expression comme celle-ci (avec SQL Server 2008)
SELECT TOP 10 columName FROM tableName
Mais au lieu de cela, j'ai besoin des valeurs comprises entre 10 et 20. Et je me demande s'il est possible de le faire en utilisant une seule instruction SELECT.
Par exemple, cela ne sert à rien:
SELECT columName FROM
(SELECT ROW_NUMBER() OVER(ORDER BY someId) AS RowNum, * FROM tableName) AS alias
WHERE RowNum BETWEEN 10 AND 20
Parce que la sélection entre crochets renvoie déjà tous les résultats, et je cherche à l'éviter pour des raisons de performance.
Il y a une astuce avec row_number
qui n'implique pas de trier toutes les lignes.
Essaye ça:
SELECT columName
FROM (SELECT ROW_NUMBER() OVER(ORDER BY (select NULL as noorder)) AS RowNum, *
FROM tableName
) as alias
WHERE RowNum BETWEEN 10 AND 20
Vous ne pouvez pas utiliser une constante dans le order by
. Toutefois, vous pouvez utiliser une expression qui renvoie une constante. SQL Server le reconnaît et renvoie simplement les lignes telles qu’elles ont été rencontrées, correctement énumérées.
Pourquoi pensez-vous que SQL Server évaluerait l'intégralité de la requête interne? En supposant que votre colonne de tri soit indexée, il ne vous reste plus qu'à lire les 20 premières valeurs. Si vous êtes vraiment nerveux, vous pouvez le faire:
Select
Id
From (
Select Top 20 -- note top 20
Row_Number() Over(Order By Id) As RowNum,
Id
From
dbo.Test
Order By
Id
) As alias
Where
RowNum Between 10 And 20
Order By
Id
mais je suis presque sûr que le plan de requête est le même dans les deux cas.
(Vraiment) Corrigé selon le commentaire d'Aaron.
Utilisez SQL Server 2012 pour récupérer/ignorer!
SELECT SalesOrderID, SalesOrderDetailID, ProductID, OrderQty, UnitPrice, LineTotal
FROM AdventureWorks2012.Sales.SalesOrderDetail
OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;
Rien de mieux que ce que vous décrivez pour les anciennes versions de SQL Server. Peut-être utiliser le CTE, mais il est peu probable que cela fasse une différence.
WITH NumberedMyTable AS
(
SELECT
Id,
Value,
ROW_NUMBER() OVER (ORDER BY Id) AS RowNumber
FROM
MyTable
)
SELECT
Id,
Value
FROM
NumberedMyTable
WHERE
RowNumber BETWEEN @From AND @To
ou bien, vous pouvez supprimer les 10 premières lignes et obtenir les 10 suivantes, mais je double tout le monde.
Une autre option
SELECT TOP(11) columName
FROM dbo.tableName
ORDER BY
CASE WHEN ROW_NUMBER() OVER (ORDER BY someId) BETWEEN 10 AND 20
THEN ROW_NUMBER() OVER (ORDER BY someId) ELSE NULL END DESC
Vous pouvez créer une table temporaire ordonnée comme vous le souhaitez:
SELECT ROW_NUMBER () OVER (ORDER BY someId) AS RowNum, * FROM nomTable Dans ## tempTable ...
De cette façon, vous avez une liste ordonnée de lignes ..__ et vous pouvez simplement interroger les numéros suivants par numéro de ligne au lieu d'effectuer plusieurs fois l'interrogation interne.