Apakah ada cara di SQL Server untuk mendapatkan hasil mulai dari offset yang diberikan? Sebagai contoh, dalam tipe lain dari database SQL, itu mungkin dilakukan:
SELECT * FROM MyTable OFFSET 50 LIMIT 25
untuk mendapatkan hasil 51-75. Konstruk ini tampaknya tidak ada di SQL Server.
Bagaimana saya bisa menyelesaikan ini tanpa memuat semua baris yang tidak saya pedulikan? Terima kasih!
sql
sql-server
Alex
sumber
sumber
Jawaban:
Saya akan menghindari penggunaan
SELECT *
. Tentukan kolom yang sebenarnya Anda inginkan walaupun mungkin semuanya.SQL Server 2005+
SQL Server 2000
Paging Efisien Melalui Set Hasil Besar di SQL Server 2000
Metode yang Lebih Efisien untuk Paging Melalui Set Hasil Besar
sumber
SELECT *
berarti bahwa jika struktur tabel berubah, kueri Anda masih berjalan, tetapi memberikan hasil yang berbeda. Jika kolom ditambahkan, ini mungkin berguna (meskipun Anda masih harus menggunakannya dengan nama di suatu tempat); jika sebuah kolom dihapus atau diganti namanya, lebih baik bagi SQL Anda untuk memecah tampak daripada kode lebih lanjut berperilaku aneh karena variabel tidak diinisialisasi.Jika Anda akan memproses semua halaman secara berurutan, maka cukup dengan mengingat nilai kunci terakhir yang terlihat pada halaman sebelumnya dan menggunakan
TOP (25) ... WHERE Key > @last_key ORDER BY Key
dapat menjadi metode dengan kinerja terbaik jika ada indeks yang sesuai untuk memungkinkan ini dicari secara efisien - atau kursor API jika tidak .Untuk memilih halaman arbiter solusi terbaik untuk SQL Server 2005 - 2008 R2 mungkin
ROW_NUMBER
danBETWEEN
Untuk SQL Server 2012+ Anda dapat menggunakan klausa ORDER BY yang ditingkatkan untuk kebutuhan ini.
Meskipun masih harus dilihat seberapa baik kinerja opsi ini .
sumber
Ini adalah salah satu cara (SQL2000)
dan ini adalah cara lain (SQL 2005)
sumber
Anda dapat menggunakan
ROW_NUMBER()
fungsi untuk mendapatkan apa yang Anda inginkan:sumber
Ada
OFFSET .. FETCH
di SQL Server 2012, tetapi Anda harus menentukanORDER BY
kolom.Jika Anda benar-benar tidak memiliki kolom eksplisit yang dapat Anda lewati sebagai
ORDER BY
kolom (seperti yang disarankan orang lain), maka Anda dapat menggunakan trik ini:... atau
Kami menggunakannya di jOOQ ketika pengguna tidak secara spesifik menentukan pesanan. Ini kemudian akan menghasilkan pemesanan yang cukup acak tanpa biaya tambahan.
sumber
Untuk tabel dengan kolom data yang lebih banyak dan besar, saya lebih suka:
-
Ini memiliki kinerja yang jauh lebih baik pada tabel dengan data besar seperti BLOB, karena fungsi ROW_NUMBER hanya perlu melihat satu kolom, dan hanya baris yang cocok dikembalikan dengan semua kolom.
sumber
Lihat pilih saya untuk paginator
Ini memecahkan pagination;)
sumber
sumber
Tergantung pada versi Anda, Anda tidak dapat melakukannya secara langsung, tetapi Anda dapat melakukan sesuatu seperti peretasan
di mana 'bidang' adalah kuncinya.
sumber
Berikut ini akan menampilkan 25 catatan tidak termasuk 50 catatan pertama bekerja di SQL Server 2012.
Anda dapat mengganti ID sebagai kebutuhan Anda
sumber
Anda harus berhati-hati ketika menggunakan
ROW_NUMBER() OVER (ORDER BY)
pernyataan karena kinerjanya sangat buruk. Hal yang sama berlaku untuk menggunakan Common Table Expressions denganROW_NUMBER()
itu bahkan lebih buruk. Saya menggunakan cuplikan berikut yang telah terbukti sedikit lebih cepat daripada menggunakan variabel tabel dengan identitas untuk memberikan nomor halaman.sumber
Saya menggunakan teknik ini untuk pagination. Saya tidak mengambil semua baris. Misalnya, jika halaman saya perlu menampilkan 100 baris teratas, saya hanya mengambil 100 dengan klausa where. Output dari SQL harus memiliki kunci unik.
Tabelnya memiliki yang berikut:
Peringkat yang sama akan ditugaskan untuk lebih dari satu KeyId.
SQL adalah
select top 2 * from Table1 where Rank >= @Rank and ID > @Id
Untuk pertama kalinya saya lulus 0 untuk keduanya. Kali kedua lulus 1 & 14. Kali ketiga berlalu 2 dan 6 ....
Nilai catatan 10 Peringkat & Id diteruskan ke yang berikutnya
Ini akan memiliki paling sedikit tekanan pada sistem
sumber
Di SqlServer2005 Anda dapat melakukan hal berikut:
sumber
@Offset + @Limit - 1
? Jika @ Batas adalah 10, ini akan menghasilkan 11 baris.Cara terbaik untuk melakukannya tanpa membuang waktu untuk memesan catatan adalah seperti ini:
dibutuhkan kurang dari satu detik!
solusi terbaik untuk tabel besar.
sumber
Saya telah mencari jawaban ini untuk sementara waktu sekarang (untuk pertanyaan umum) dan menemukan cara lain untuk melakukannya di SQL Server 2000+ menggunakan ROWCOUNT dan kursor dan tanpa TOP atau tabel sementara.
Dengan menggunakan
SET ROWCOUNT [OFFSET+LIMIT]
Anda dapat membatasi hasil, dan dengan kursor, langsung ke baris yang Anda inginkan, lalu loop 'sampai akhir.Jadi kueri Anda akan seperti ini:
sumber
Dengan SQL Server 2012 (11.x) dan yang lebih baru dan Azure SQL Database, Anda juga dapat memiliki "fetch_row_count_expression", Anda juga dapat memiliki klausa ORDER BY bersama dengan ini.
https://docs.microsoft.com/en-us/sql/t-sql/queries/select-order-by-clause-transact-sql?view=sql-server-ver15
Catatan OFFSET Menentukan jumlah baris yang dilewati sebelum mulai mengembalikan baris dari ekspresi kueri. Ini BUKAN nomor baris awal. Jadi, harus 0 untuk memasukkan catatan pertama.
sumber