Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Pagination di SQL Server menggunakan OFFSET/FETCH

Pagination sering digunakan dalam aplikasi di mana pengguna dapat mengklik Sebelumnya /Selanjutnya untuk menavigasi halaman yang membentuk hasil, atau klik nomor halaman untuk langsung membuka halaman tertentu.

Saat menjalankan kueri di SQL Server, Anda dapat membuat paginasi hasilnya dengan menggunakan OFFSET dan FETCH argumen dari ORDER BY ayat. Argumen ini diperkenalkan di SQL Server 2012, oleh karena itu Anda dapat menggunakan teknik ini jika Anda memiliki SQL Server 2012 atau lebih tinggi.

Dalam konteks ini, pagination adalah tempat Anda membagi hasil kueri menjadi potongan-potongan yang lebih kecil, setiap potongan melanjutkan di mana yang sebelumnya selesai. Misalnya, jika kueri mengembalikan 1000 baris, Anda dapat membuat paginasinya sehingga dikembalikan dalam kelompok 100. Aplikasi dapat meneruskan nomor halaman dan ukuran halaman ke SQL Server, dan SQL Server kemudian dapat menggunakannya untuk mengembalikan hanya data untuk halaman yang diminta.

Contoh 1 – Tanpa Pagination

Pertama, mari kita jalankan kueri yang mengembalikan semua baris dalam tabel:

SELECT *
FROM Genres
ORDER BY GenreId;

Hasil:

+-----------+---------+
| GenreId   | Genre   |
|-----------+---------|
| 1         | Rock    |
| 2         | Jazz    |
| 3         | Country |
| 4         | Pop     |
| 5         | Blues   |
| 6         | Hip Hop |
| 7         | Rap     |
| 8         | Punk    |
+-----------+---------+

Contoh ini tidak menggunakan pagination – semua hasil ditampilkan.

Kumpulan hasil ini sangat kecil sehingga biasanya tidak memerlukan pagination, tetapi untuk tujuan artikel ini, mari kita membuat paginasi.

Contoh 2 – Menampilkan 3 Hasil Pertama

Contoh ini menampilkan tiga hasil pertama:

SELECT *
FROM Genres
ORDER BY GenreId
  OFFSET 0 ROWS
  FETCH NEXT 3 ROWS ONLY;

Hasil:

+-----------+---------+
| GenreId   | Genre   |
|-----------+---------|
| 1         | Rock    |
| 2         | Jazz    |
| 3         | Country |
+-----------+---------+

Dalam hal ini, saya menentukan bahwa hasil harus dimulai dari hasil pertama dan menampilkan tiga baris berikutnya. Ini dilakukan dengan menggunakan yang berikut ini:

  • OFFSET 0 ROWS menentukan bahwa tidak boleh ada offset (offset nol).
  • FETCH NEXT 3 ROWS ONLY mendapat tiga baris berikutnya dari offset. Karena saya menetapkan offset nol, tiga baris pertama diambil.

Jika yang kami inginkan hanyalah 3 hasil teratas, kami dapat mencapai hasil yang sama dengan menggunakan TOP klausa alih-alih menentukan nilai offset dan fetch. Namun, ini tidak memungkinkan kami untuk melakukan bagian selanjutnya.

Contoh 3 – Menampilkan 3 Hasil Selanjutnya

Sekarang mari kita tampilkan tiga hasil berikutnya:

SELECT *
FROM Genres
ORDER BY GenreId
  OFFSET 3 ROWS
  FETCH NEXT 3 ROWS ONLY;

Hasil:

+-----------+---------+
| GenreId   | Genre   |
|-----------+---------|
| 4         | Pop     |
| 5         | Blues   |
| 6         | Hip Hop |
+-----------+---------+

Jadi satu-satunya yang saya ubah adalah offsetnya.

Nilai offset dan pengambilan juga dapat berupa ekspresi yang disediakan sebagai variabel, parameter, atau subkueri skalar konstan. Saat subkueri digunakan, subkueri tidak dapat mereferensikan kolom apa pun yang ditentukan dalam cakupan kueri luar (tidak dapat dikorelasikan dengan kueri luar).

Contoh berikut menggunakan ekspresi untuk menunjukkan dua pendekatan untuk membuat halaman hasil.

Contoh 4 – Paginasi dengan Nomor Baris

Contoh ini menggunakan ekspresi untuk menentukan baris nomor untuk memulai.

DECLARE 
  @StartRow int = 1,
  @RowsPerPage int = 3;
  
SELECT *  
FROM Genres
ORDER BY GenreId ASC
    OFFSET @StartRow - 1 ROWS
    FETCH NEXT @RowsPerPage ROWS ONLY;

Hasil:

+-----------+---------+
| GenreId   | Genre   |
|-----------+---------|
| 1         | Rock    |
| 2         | Jazz    |
| 3         | Country |
+-----------+---------+

Di sini, saya menggunakan @StartRow int = 1 untuk menentukan bahwa hasil harus dimulai dari baris pertama.

Inilah yang terjadi jika saya menaikkan nilai itu menjadi 2 .

DECLARE 
  @StartRow int = 2,
  @RowsPerPage int = 3;
  
SELECT *  
FROM Genres
ORDER BY GenreId ASC
    OFFSET @StartRow - 1 ROWS
    FETCH NEXT @RowsPerPage ROWS ONLY;

Hasil:

+-----------+---------+
| GenreId   | Genre   |
|-----------+---------|
| 2         | Jazz    |
| 3         | Country |
| 4         | Pop     |
+-----------+---------+

Itu dimulai dari baris kedua. Dengan menggunakan metode ini, saya dapat menentukan baris yang tepat untuk memulai.

Contoh 5 – Paginasi berdasarkan Nomor Halaman

Contoh ini hampir identik dengan contoh sebelumnya, kecuali bahwa ini memungkinkan Anda untuk menentukan nomor halaman, sebagai lawan dari nomor baris.

DECLARE 
  @PageNumber int = 1,
  @RowsPerPage int = 3;
  
SELECT *  
FROM Genres
ORDER BY GenreId ASC
    OFFSET (@PageNumber - 1) * @RowsPerPage ROWS
    FETCH NEXT @RowsPerPage ROWS ONLY;

Hasil:

+-----------+---------+
| GenreId   | Genre   |
|-----------+---------|
| 1         | Rock    |
| 2         | Jazz    |
| 3         | Country |
+-----------+---------+

Jadi hasil pertama adalah sama. Namun, mari kita lihat apa yang terjadi ketika kita menambahkan @PageNumber ke 2 (Saya mengganti nama variabel ini untuk mencerminkan tujuan barunya).

DECLARE 
  @PageNumber int = 2,
  @RowsPerPage int = 3;
  
SELECT *  
FROM Genres
ORDER BY GenreId ASC
    OFFSET (@PageNumber - 1) * @RowsPerPage ROWS
    FETCH NEXT @RowsPerPage ROWS ONLY;

Hasil:

+-----------+---------+
| GenreId   | Genre   |
|-----------+---------|
| 4         | Pop     |
| 5         | Blues   |
| 6         | Hip Hop |
+-----------+---------+

Kali ini hasil dimulai dari baris keempat. Jadi dengan menggunakan metode ini, Anda cukup memasukkan nomor halaman daripada nomor baris.

Contoh 6 – Pengulangan Pagination

Untuk menyelesaikannya, berikut adalah contoh cepat yang mengulang semua halaman dan menentukan nomor baris awal untuk setiap iterasi:

DECLARE 
  @StartRow int = 1, 
  @RowsPerPage int = 3;
WHILE (SELECT COUNT(*) FROM Genres) >= @StartRow  
BEGIN
    SELECT *  
    FROM Genres 
    ORDER BY GenreId ASC   
        OFFSET @StartRow - 1 ROWS   
        FETCH NEXT @RowsPerPage ROWS ONLY;
SET @StartRow = @StartRow + @RowsPerPage;  
CONTINUE
END;

Hasil:

+-----------+---------+
| GenreId   | Genre   |
|-----------+---------|
| 1         | Rock    |
| 2         | Jazz    |
| 3         | Country |
+-----------+---------+
(3 rows affected)
+-----------+---------+
| GenreId   | Genre   |
|-----------+---------|
| 4         | Pop     |
| 5         | Blues   |
| 6         | Hip Hop |
+-----------+---------+
(3 rows affected)
+-----------+---------+
| GenreId   | Genre   |
|-----------+---------|
| 7         | Rap     |
| 8         | Punk    |
+-----------+---------+
(2 rows affected)

Contoh 7 – ROW vs ROWS

Jika Anda menemukan kode yang menggunakan ROW bukannya ROWS , kedua argumen melakukan hal yang sama. Mereka adalah sinonim dan disediakan untuk kompatibilitas ANSI.

Ini adalah contoh pertama di halaman ini, tetapi dengan ROW bukannya ROWS .

SELECT *
FROM Genres
ORDER BY GenreId
  OFFSET 0 ROW
  FETCH NEXT 3 ROW ONLY;

Hasil:

+-----------+---------+
| GenreId   | Genre   |
|-----------+---------|
| 1         | Rock    |
| 2         | Jazz    |
| 3         | Country |
+-----------+---------+

Contoh 8 – PERTAMA vs BERIKUTNYA

Hal yang sama berlaku untuk FIRST dan NEXT . Ini adalah sinonim yang disediakan untuk kompatibilitas ANSI.

Ini contoh sebelumnya tetapi dengan FIRST bukannya NEXT .

SELECT *
FROM Genres
ORDER BY GenreId
  OFFSET 0 ROW
  FETCH FIRST 3 ROW ONLY;

Hasil:

+-----------+---------+
| GenreId   | Genre   |
|-----------+---------|
| 1         | Rock    |
| 2         | Jazz    |
| 3         | Country |
+-----------+---------+

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Apakah mungkin untuk menetapkan batas waktu untuk kueri SQL di Microsoft SQL Server?

  2. Konversi 'waktu' menjadi 'datetimeoffset' di SQL Server (Contoh T-SQL)

  3. Keamanan Ketat CLR di SQL Server 2017

  4. Buat Prosedur Tersimpan di SQL Server 2017

  5. Kueri SQL untuk membagi data kolom menjadi baris