Saya mengalami kesulitan saat mengubah prosedur yang tersimpan dari SQL Server ke Oracle agar produk kami kompatibel dengannya.
Saya memiliki pertanyaan yang mengembalikan catatan terbaru dari beberapa tabel, berdasarkan stempel waktu:
SQL Server:
SELECT TOP 1 *
FROM RACEWAY_INPUT_LABO
ORDER BY t_stamp DESC
=> Itu akan mengembalikan saya rekor terbaru
Tapi Oracle:
SELECT *
FROM raceway_input_labo
WHERE rownum <= 1
ORDER BY t_stamp DESC
=> Itu akan mengembalikan saya catatan tertua (mungkin tergantung pada indeks), terlepas dari ORDER BY
pernyataannya!
Saya merangkum kueri Oracle dengan cara ini agar sesuai dengan kebutuhan saya:
SELECT *
FROM
(SELECT *
FROM raceway_input_labo
ORDER BY t_stamp DESC)
WHERE rownum <= 1
dan berhasil. Tapi kedengarannya seperti retasan yang mengerikan bagi saya, terutama jika saya memiliki banyak catatan di tabel yang terlibat.
Apa cara terbaik untuk mencapai ini?
sql
oracle
sql-order-by
rownum
Larry
sumber
sumber
Jawaban:
The
where
pernyataan dijalankan sebelum iniorder by
. Jadi, kueri yang Anda inginkan mengatakan " ambil baris pertama lalut_stamp
urutkan menurut desc ". Dan bukan itu yang Anda inginkan.Metode subquery adalah metode yang tepat untuk melakukan ini di Oracle.
Jika Anda menginginkan versi yang berfungsi di kedua server, Anda dapat menggunakan:
Bagian luar
*
akan mengembalikan "1" di kolom terakhir. Anda perlu membuat daftar kolom satu per satu untuk menghindari ini.sumber
Gunakan
ROW_NUMBER()
sebagai gantinya.ROWNUM
adalah pseudocolumn danROW_NUMBER()
merupakan sebuah fungsi. Anda dapat membaca tentang perbedaan di antara mereka dan melihat perbedaan output dari kueri di bawah ini:sumber
ROWNUM
bisa lebih cepat daripadaROW_NUMBER()
jadi apakah seseorang harus menggunakan salah satu dari yang lain tergantung pada sejumlah faktor.Alternatif yang saya sarankan dalam kasus penggunaan ini adalah menggunakan MAX (t_stamp) untuk mendapatkan baris terbaru ... mis
Preferensi pola pengkodean saya (mungkin) - dapat diandalkan, umumnya berkinerja pada atau lebih baik daripada mencoba memilih baris pertama dari daftar yang diurutkan - juga maksudnya lebih dapat dibaca secara eksplisit.
Semoga ini membantu ...
SQLer
sumber
Beberapa masalah desain yang didokumentasikan dengan ini dalam komentar di atas. Singkatnya, di Oracle, Anda perlu membatasi hasil secara manual saat Anda memiliki tabel besar dan / atau tabel dengan nama kolom yang sama (dan Anda tidak ingin mengetikkan semuanya secara eksplisit dan mengganti nama semuanya). Solusi mudahnya adalah mencari tahu breakpoint Anda dan membatasinya dalam kueri Anda. Atau Anda juga bisa melakukan ini di kueri bagian dalam jika Anda tidak memiliki batasan nama kolom yang bentrok. Misalnya
akan mengurangi hasil secara substansial. Kemudian Anda dapat ORDER BY atau bahkan melakukan kueri luar untuk membatasi baris.
Juga, menurut saya TOAD memiliki fitur untuk membatasi baris; tetapi, tidak yakin bahwa tidak membatasi dalam kueri aktual di Oracle. Tidak yakin.
sumber