Szukaj…


Wprowadzenie

Przesunięcie wiersza i stronicowanie w różnych wersjach SQL Server

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

SQL Server 2008

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

SQL Server 2012

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ć klauzuli OFFSET i FETCH .
  • Klauzula OFFSET jest obowiązkowa dla FETCH . Nigdy nie możesz użyć, ORDER BYFETCH .
  • TOP nie może być łączony z OFFSET i FETCH w tym samym wyrażeniu zapytania.


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow