Saya tertarik mempelajari beberapa cara agnostik database untuk memilih baris ke- n dari tabel database. Ini juga akan menarik untuk melihat bagaimana ini dapat dicapai dengan menggunakan fungsionalitas asli dari database berikut:
- SQL Server
- MySQL
- PostgreSQL
- SQLite
- Peramal
Saat ini saya sedang melakukan sesuatu seperti berikut ini di SQL Server 2005, tetapi saya akan tertarik melihat pendekatan yang lebih agnostik:
WITH Ordered AS (
SELECT ROW_NUMBER() OVER (ORDER BY OrderID) AS RowNumber, OrderID, OrderDate
FROM Orders)
SELECT *
FROM Ordered
WHERE RowNumber = 1000000
Penghargaan untuk SQL di atas: Weblog Firoz Ansari
Pembaruan: Lihat Troels jawaban Arvin mengenai standar SQL. Troel, apakah Anda punya tautan yang bisa kami kutip?
OrderNo N
, maka perkenalkan kolom OrderSequenceNo di tabel dan hasilkan dari generator urutan independen saat membuat pesanan baru.offset x fetch first y rows only
. Saat ini didukung oleh (setidaknya) Postgres, Oracle12, DB2.Jawaban:
Ada beberapa cara untuk melakukan ini di bagian opsional standar, tetapi banyak database mendukung cara mereka sendiri untuk melakukannya.
Situs yang sangat bagus yang membicarakan hal ini dan yang lainnya adalah http://troels.arvin.dk/db/rdbms/#select-limit .
Pada dasarnya, PostgreSQL dan MySQL mendukung non-standar:
Oracle, DB2 dan MSSQL mendukung fungsi windowing standar:
(yang saya salin dari situs yang ditautkan di atas karena saya tidak pernah menggunakan DB tersebut)
Pembaruan: Pada PostgreSQL 8.4 fungsi windowing standar didukung, jadi harap contoh kedua juga berfungsi untuk PostgreSQL.
Pembaruan: SQLite menambahkan dukungan fungsi jendela di versi 3.25.0 pada 2018-09-15 sehingga kedua bentuk juga berfungsi di SQLite.
sumber
WHERE rownumber = n
mendapatkan baris ke-n saja?PostgreSQL mendukung fungsi windowing seperti yang didefinisikan oleh standar SQL, tetapi mereka canggung, jadi kebanyakan orang menggunakan (non-standar)
LIMIT
/OFFSET
:Contoh ini memilih baris ke-21.
OFFSET 20
memberitahu Postgres untuk melewati 20 catatan pertama. Jika Anda tidak menentukanORDER BY
klausa, tidak ada jaminan catatan mana yang akan Anda dapatkan, yang jarang berguna.sumber
Saya tidak yakin tentang yang lain, tapi saya tahu SQLite dan MySQL tidak memiliki urutan baris "default". Dalam dua dialek itu, paling tidak, cuplikan berikut ini mengambil entri ke-15 dari the_table, mengurutkan berdasarkan tanggal / waktu penambahannya:
(tentu saja, Anda harus memiliki bidang DATETIME yang ditambahkan, dan mengaturnya ke tanggal / waktu ketika entri ditambahkan ...)
sumber
SQL 2005 dan di atasnya memiliki fitur ini bawaan. Gunakan fungsi ROW_NUMBER (). Sangat bagus untuk halaman web dengan penjelajahan gaya << Sebelumnya dan Selanjutnya >>:
Sintaksis:
sumber
Saya menduga ini sangat tidak efisien tetapi pendekatan yang cukup sederhana, yang bekerja pada dataset kecil yang saya coba.
Ini akan mendapatkan item ke-5, mengubah nomor top kedua untuk mendapatkan item ke-n yang berbeda
Hanya SQL server (saya pikir) tetapi harus berfungsi pada versi yang lebih lama yang tidak mendukung ROW_NUMBER ().
sumber
1 perubahan kecil: n-1 bukannya n.
sumber
Verifikasi di SQL Server:
Ini akan memberi Anda 10 baris tabel emp!
sumber
Bertentangan dengan apa yang diklaim oleh beberapa jawaban, standar SQL tidak membisu mengenai subjek ini.
Sejak SQL: 2003, Anda telah dapat menggunakan "fungsi jendela" untuk melewati baris dan membatasi set hasil.
Dan dalam SQL: 2008, pendekatan yang sedikit lebih sederhana telah ditambahkan, menggunakan
OFFSET skip ROWS FETCH FIRST n ROWS ONLY
Secara pribadi, saya tidak berpikir bahwa penambahan SQL: 2008 benar-benar diperlukan, jadi jika saya ISO, saya akan membuatnya keluar dari standar yang sudah agak besar.
sumber
Ketika kami dulu bekerja di MSSQL 2000, kami melakukan apa yang kami sebut "triple-flip":
Diedit
Itu tidak elegan, dan tidak cepat, tetapi berhasil.
sumber
IF / ELSE IF
blok di bawahOuterPageSize
perhitungan - pada halaman 1 dan 2, mereka akan menurunkanOuterPageSize
nilainya kembali menjadi 10. Pada halaman 3 (baris 21-25) perhitungan akan kembali dengan benar 5, dan pada semua halaman 4 dan lebih besar, hasil negatif dari perhitungan akan diganti dengan 0 (meskipun mungkin akan lebih cepat untuk mengembalikan baris data kosong segera pada saat itu).Pilih catatan ke-n dari atas
pilih catatan ke-n dari bawah
sumber
Peramal:
sumber
where ROWNUM = x
hanya akan bekerja untuk x = 1 di Oracle DB. yaituwhere ROWNUM = 2
tidak akan mengembalikan baris.Di Oracle 12c, Anda dapat menggunakan
OFFSET..FETCH..ROWS
opsi denganORDER BY
Misalnya, untuk mendapatkan catatan ke-3 dari atas:
sumber
Inilah solusi cepat dari kebingungan Anda.
Di sini Anda bisa mendapatkan baris Terakhir dengan Mengisi N = 0, Kedua terakhir dengan N = 1, Keempat Terakhir Dengan Mengisi N = 3 dan seterusnya.
Ini adalah pertanyaan yang sangat umum selama wawancara dan ini sangat sederhana.
Lebih lanjut Jika Anda ingin Jumlah, ID atau Urutan Sortasi Numerik daripada yang Anda gunakan untuk fungsi CAST di MySQL.
Di Sini Dengan mengisi N = 4 Anda akan bisa mendapatkan Catatan Terakhir Kelima dari Jumlah Tertinggi dari tabel CART. Anda dapat menyesuaikan nama bidang dan tabel Anda dan menghasilkan solusi.
sumber
MENAMBAHKAN:
Itu akan membatasi hasil untuk satu hasil mulai dari hasil n.
sumber
Misalnya, jika Anda ingin memilih setiap baris ke-10 di MSSQL, Anda dapat menggunakan;
Ambil saja MOD dan ubah nomor 10 di sini nomor yang Anda inginkan.
sumber
Untuk SQL Server, cara umum untuk menggunakan nomor baris adalah sebagai berikut:
Sebagai contoh:
Ini akan mengembalikan informasi baris ke-20. Pastikan untuk memasukkan rowcount 0 sesudahnya.
sumber
LIMIT n, 1 tidak berfungsi di MS SQL Server. Saya pikir ini hanya tentang satu-satunya database utama yang tidak mendukung sintaks itu. Agar adil, itu bukan bagian dari standar SQL, meskipun begitu banyak didukung sehingga seharusnya. Dalam segala hal kecuali LIMIT SQL server berfungsi dengan baik. Untuk SQL server, saya belum dapat menemukan solusi yang elegan.
sumber
Berikut ini adalah versi umum dari sproc yang baru-baru ini saya tulis untuk Oracle yang memungkinkan paging / sorting dinamis - HTH
sumber
Tapi sungguh, bukankah ini hanya trik sulap untuk desain database yang bagus? Beberapa kali saya membutuhkan fungsionalitas seperti ini, permintaan sederhana untuk membuat laporan cepat. Untuk pekerjaan nyata, menggunakan trik seperti ini mengundang masalah. Jika memilih baris tertentu diperlukan maka hanya memiliki kolom dengan nilai sekuensial dan selesai dengannya.
sumber
Untuk SQL server, berikut ini akan mengembalikan baris pertama dari tabel pemberian.
Anda dapat mengulangi nilai dengan sesuatu seperti ini:
sumber
Dalam Sybase SQL Anywhere:
Jangan lupa ORDER OLEH atau tidak ada artinya.
sumber
T-SQL - Memilih NNth RecordNumber dari Tabel
Untuk misalnya memilih catatan ke-5 dari tabel Karyawan, permintaan Anda seharusnya
sumber
sumber
Saya telah menulis kueri ini untuk menemukan baris ke-N. Contoh dengan kueri ini adalah
sumber
sulit dipercaya bahwa Anda dapat menemukan mesin SQL yang menjalankan yang ini ...
sumber
Tidak ada yang mewah, tidak ada fungsi khusus, jika Anda menggunakan Caché seperti yang saya lakukan ...
Mengingat Anda memiliki kolom ID atau kolom stempel data yang dapat Anda percayai.
sumber
Ini adalah bagaimana saya akan melakukannya dalam DB2 SQL, saya percaya RRN (nomor catatan relatif) disimpan dalam tabel oleh O / S;
sumber
Pertama-tama pilih 100 baris teratas dengan memesan dalam naik dan kemudian pilih baris terakhir dengan memesan dalam turun dan batasi ke 1. Namun ini adalah pernyataan yang sangat mahal karena mengakses data dua kali.
sumber
Tampak bagi saya bahwa, agar efisien, Anda perlu 1) menghasilkan angka acak antara 0 dan satu kurang dari jumlah catatan basis data, dan 2) dapat memilih baris pada posisi itu. Sayangnya, database yang berbeda memiliki generator angka acak yang berbeda dan cara yang berbeda untuk memilih baris pada posisi dalam set hasil - biasanya Anda menentukan berapa banyak baris untuk dilewati dan berapa banyak baris yang Anda inginkan, tetapi itu dilakukan secara berbeda untuk database yang berbeda. Ini adalah sesuatu yang bekerja untuk saya dalam SQLite:
Itu tergantung pada kemampuan untuk menggunakan subquery dalam klausa batas (yang dalam SQLite adalah LIMIT <recs to skip>, <recs to take>) Memilih jumlah record dalam sebuah tabel harus sangat efisien, menjadi bagian dari database meta data, tetapi itu tergantung pada implementasi database. Juga, saya tidak tahu apakah kueri benar-benar akan membangun set hasil sebelum mengambil catatan Nth, tapi saya berharap itu tidak perlu. Perhatikan bahwa saya tidak menentukan klausa "pesanan menurut". Mungkin lebih baik untuk "memesan dengan" sesuatu seperti kunci utama, yang akan memiliki indeks - mendapatkan catatan N dari indeks mungkin lebih cepat jika database tidak bisa mendapatkan catatan N dari database itu sendiri tanpa membangun set hasil .
sumber
Jawaban yang paling cocok saya lihat di artikel ini untuk sql server
sumber