Microsoft SQL Server
Paginacja
Szukaj…
Wprowadzenie
Składnia
- WYBIERZ * Z NAZWY TABELI ZAMÓWIENIE wg id PRZESUNIĘCIE TYLKO 10 RZĘDÓW POBIERZ TYLKO 10 RZĘDÓW;
Podział na strony przy użyciu ROW_NUMBER ze wspólnym wyrażeniem tabelowym
Funkcja ROW_NUMBER
może przypisać liczbę rosnącą do każdego wiersza w zestawie wyników. W połączeniu ze wspólnym wyrażeniem tabelowym, które korzysta z operatora BETWEEN
, możliwe jest tworzenie „stron” zestawów wyników. Na przykład: strona pierwsza zawiera wyniki 1-10, strona druga zawiera wyniki 11-20, strona trzecia zawiera wyniki 21-30 i tak dalej.
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
Uwaga: Nie można użyć parametru ROW_NUMBER
w klauzuli WHERE
, takiej jak:
SELECT object_id,
name,
type,
create_date
FROM sys.objects
WHERE ROW_NUMBER() OVER (ORDER BY name) BETWEEN 41 AND 50
Chociaż byłoby to wygodniejsze, serwer SQL zwróci w tym przypadku następujący błąd:
Msg 4108, poziom 15, stan 1, wiersz 6
Funkcje okienkowe mogą pojawiać się tylko w klauzulach SELECT lub ORDER BY.
Paginacja za pomocą OFFSET FETCH
Klauzula OFFSET FETCH
implementuje paginację w bardziej zwięzły sposób. Dzięki niemu można pominąć wiersze N1 (określone w OFFSET
) i zwrócić kolejne wiersze N2 (określone w FETCH
):
SELECT *
FROM sys.objects
ORDER BY object_id
OFFSET 40 ROWS FETCH NEXT 10 ROWS ONLY
Klauzula ORDER BY
jest wymagana w celu zapewnienia deterministycznych wyników.
Paginaton z wewnętrznym zapytaniem
We wcześniejszych wersjach SQL Server programiści musieli stosować podwójne sortowanie w połączeniu ze słowem kluczowym TOP
aby zwrócić wiersze na stronie:
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
Wewnętrzne zapytanie zwróci pierwsze 50 wierszy uporządkowanych według name
. Następnie zapytanie zewnętrzne odwróci kolejność tych 50 wierszy i wybierze 10 górnych wierszy (będą to ostatnie 10 wierszy w grupie przed odwróceniem).
Stronicowanie w różnych wersjach 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 przy użyciu ORDER BY OFFSET i FETCH NEXT
Aby uzyskać kolejne 10 wierszy, wystarczy uruchomić to zapytanie:
SELECT * FROM TableName ORDER BY id OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;
Najważniejsze kwestie, które należy wziąć pod uwagę podczas korzystania z niego:
-
ORDER BY
jest obowiązkowe, aby użyć klauzuliOFFSET
iFETCH
. - Klauzula
OFFSET
jest obowiązkowa dlaFETCH
. Nigdy nie możesz użyć,ORDER BY
…FETCH
. -
TOP
nie może być łączony zOFFSET
iFETCH
w tym samym wyrażeniu zapytania.