Microsoft SQL Server
paginatura
Ricerca…
introduzione
Sintassi
- SELECT * FROM TableName ORDINA DA id OFFSET 10 ROWS FETCH NEXT 10 ROWS SOLO;
Impaginazione utilizzando ROW_NUMBER con un'espressione tabella comune
La funzione ROW_NUMBER
può assegnare un numero incrementale a ciascuna riga in un set di risultati. Combinato con un'espressione di tabella comune che utilizza un operatore BETWEEN
, è possibile creare "pagine" di set di risultati. Ad esempio: pagina uno contenente i risultati 1-10, pagina due contenente i risultati 11-20, pagina 3 contenente i risultati 21-30 e così via.
WITH data
AS
(
SELECT ROW_NUMBER() OVER (ORDER BY name) AS row_id,
object_id,
name,
type,
create_date
FROM sys.objects
)
SELECT *
FROM data
WHERE row_id BETWEEN 41 AND 50
Nota: non è possibile utilizzare ROW_NUMBER
in una clausola WHERE
come:
SELECT object_id,
name,
type,
create_date
FROM sys.objects
WHERE ROW_NUMBER() OVER (ORDER BY name) BETWEEN 41 AND 50
Sebbene ciò sia più conveniente, SQL Server restituirà il seguente errore in questo caso:
Messaggio 4108, livello 15, stato 1, riga 6
Le funzioni di finestra possono essere visualizzate solo nelle clausole SELECT o ORDER BY.
Paginazione con OFFSET FETCH
La clausola OFFSET FETCH
implementa la paginazione in modo più conciso. Con esso, è possibile saltare le righe N1 (specificate in OFFSET
) e restituire le successive righe N2 (specificate in FETCH
):
SELECT *
FROM sys.objects
ORDER BY object_id
OFFSET 40 ROWS FETCH NEXT 10 ROWS ONLY
La clausola ORDER BY
è necessaria per fornire risultati deterministici.
Paginaton con query interna
Nelle versioni precedenti di SQL Server, gli sviluppatori dovevano utilizzare il doppio ordinamento combinato con la parola chiave TOP
per restituire righe in una pagina:
SELECT TOP 10 *
FROM
(
SELECT
TOP 50 object_id,
name,
type,
create_date
FROM sys.objects
ORDER BY name ASC
) AS data
ORDER BY name DESC
La query interna restituirà le prime 50 righe ordinate per name
. Quindi la query esterna invertirà l'ordine di queste 50 righe e selezionerà le prime 10 righe (queste ultime saranno le ultime 10 righe nel gruppo prima dell'inversione).
Cercapersone in varie versioni di SQL Server
SQL Server 2012/2014
DECLARE @RowsPerPage INT = 10, @PageNumber INT = 4
SELECT OrderId, ProductId
FROM OrderDetail
ORDER BY OrderId
OFFSET (@PageNumber - 1) * @RowsPerPage ROWS
FETCH NEXT @RowsPerPage ROWS ONLY
SQL Server 2005/2008 / R2
DECLARE @RowsPerPage INT = 10, @PageNumber INT = 4
SELECT OrderId, ProductId
FROM (
SELECT OrderId, ProductId, ROW_NUMBER() OVER (ORDER BY OrderId) AS RowNum
FROM OrderDetail) AS OD
WHERE OD.RowNum BETWEEN ((@PageNumber - 1 ) * @RowsPerPage) + 1
AND @RowsPerPage * @PageNumber
SQL Server 2000
DECLARE @RowsPerPage INT = 10, @PageNumber INT = 4
SELECT OrderId, ProductId
FROM (SELECT TOP (@RowsPerPage) OrderId, ProductId
FROM (SELECT TOP ((@PageNumber)*@RowsPerPage) OrderId, ProductId
FROM OrderDetail
ORDER BY OrderId) AS OD
ORDER BY OrderId DESC) AS OD2
ORDER BY OrderId ASC
SQL Server 2012/2014 utilizzando ORDER BY OFFSET e FETCH NEXT
Per ottenere le 10 righe successive, esegui questa query:
SELECT * FROM TableName ORDER BY id OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;
Punti chiave da considerare quando lo si utilizza:
-
ORDER BY
è obbligatorio per utilizzare la clausolaOFFSET
eFETCH
. -
OFFSET
clausolaOFFSET
è obbligatoria conFETCH
. Non puoi mai usare,ORDER BY
...FETCH
. -
TOP
non può essere combinato conOFFSET
eFETCH
nella stessa espressione di query.