Saya punya tabel SQL dengan bidang datetime. Bidang yang dimaksud dapat berupa nol. Saya punya pertanyaan dan saya ingin hasil diurutkan secara naik-turun oleh bidang datetime, namun saya ingin baris di mana bidang datetime adalah nol di akhir daftar, bukan di awal.
Apakah ada cara sederhana untuk mencapainya?
sql
sorting
sql-order-by
David Božjak
sumber
sumber
Jawaban:
sumber
order by case when MyDate is null then 1 else 0 end
adalah cara yang sangat panjang untuk mengatakanORDER BY MyDate IS NULL
order by 0
ditafsirkan sebagai indeks kolom, dan indeks kolom berbasis 1. Untuk mengurutkan kueri menurut kolom ke-3 Anda bisa mengatakanorder by 3
(yang merupakan ide buruk untuk permintaan produksi), tetapi sangat berguna (seperti*
) saat bereksperimen.(Sedikit "terlambat", tetapi ini belum disebutkan sama sekali)
Anda tidak menentukan DBMS Anda.
Dalam SQL standar (dan kebanyakan DBMS modern seperti Oracle, PostgreSQL, DB2, Firebird, Apache Derby, HSQLDB, dan H2) Anda dapat menentukan
NULLS LAST
atauNULLS FIRST
:Gunakan
NULLS LAST
untuk mengurutkan mereka sampai akhir:sumber
NULLS FIRST
danNULLS LAST
telah ditambahkan dalam SQL: 2003 tetapi tidak ada implementasi standar yang tersedia di seluruh DMBS berbeda. Tergantung pada mesin database, gunakanORDER BY expr some_column DESC NULLS LAST
(Oracle),ORDER BY ISNULL(some_column, 1), some_column ASC
(MSSQL) atauORDER BY ISNULL(some_column), some_column ASC
(MySQL dengan implementasi ISNULL () yang berbeda).ASC
/DESC
dengan nulls beberapa lakukan. Jadi satu-satunya cara untuk memastikan ini, adalah menggunakanNULL FIRST/LAST
jika DBMS mendukungnya. Itu mendokumentasikan apa yang Anda inginkan. Penggunaanisnull()
atau fungsi lainnya adalah solusi untuk dukungan yang hilang untukNULLS FIRST/LAST
(yang didukung oleh Oracle, PostgreSQL, DB2, Firebird, Apache Derby, HSQLDB dan H2)expr
kata kunci saat menggunakan NULLS FIRST / LAST. Dan terima kasih tentang nulls yang ditampilkan pertama / terakhir bervariasi dari tipe database ke tipe, tidak tahu itu!NULLS LAST
tidak berfungsi di database MySQL saya.Saya juga menemukan ini dan berikut ini sepertinya melakukan trik untuk saya, pada MySQL dan PostgreSQL:
seperti yang ditemukan di https://stackoverflow.com/a/7055259/496209
sumber
IS NULL
danIS NOT NULL
tidak berhasil di database MySQL saya.sumber
Anda dapat menggunakan fungsi bawaan untuk memeriksa nol atau tidak, seperti di bawah ini. Saya mengujinya dan berfungsi dengan baik.
select MyDate from MyTable order by ISNULL(MyDate,1) DESC, MyDate ASC;
sumber
ISNULL(MyDate) DESC, MyDate ASC
, tetapi tidak mengurutkan dalam urutan yang benar.Jika mesin Anda memungkinkan
ORDER BY x IS NULL, x
atauORDER BY x NULLS LAST
menggunakannya. Tetapi jika tidak, ini mungkin membantu:Jika Anda mengurutkan berdasarkan tipe numerik, Anda dapat melakukan ini: (Meminjam skema dari jawaban lain .)
Setiap angka yang bukan nol menjadi 0, dan nol menjadi 1, yang merupakan jenis nol yang terakhir.
Anda juga dapat melakukan ini untuk string:
Karena
'a'
>''
.Ini bahkan bekerja dengan tanggal dengan memaksa ke int nullable dan menggunakan metode untuk int di atas:
(Mari kita berpura-pura skema memiliki HireDate.)
Metode ini menghindari masalah harus datang dengan atau mengelola nilai "maksimum" dari setiap jenis atau memperbaiki kueri jika tipe data (dan maksimum) berubah (kedua masalah yang diderita oleh solusi ISNULL lain). Plus mereka jauh lebih pendek daripada KASUS.
sumber
Saat kolom pesanan Anda berupa angka (seperti peringkat), Anda dapat mengalikannya dengan -1 dan kemudian memesan menurun. Ini akan menjaga urutan yang Anda harapkan tetapi menempatkan NULL sebagai yang terakhir.
sumber
Lihat posting blog ini .
sumber
Terima kasih RedFilter untuk memberikan solusi yang sangat baik untuk masalah penyortiran bidang pengurutan data nullable.
Saya menggunakan database SQL Server untuk proyek saya.
Mengubah nilai nol datetime ke '1' memang memecahkan masalah pengurutan untuk kolom datatype datetime. Namun jika kita memiliki kolom dengan selain datatype maka gagal untuk menangani.
Untuk menangani semacam kolom varchar, saya mencoba menggunakan 'ZZZZZZZ' karena saya tahu kolom tidak memiliki nilai yang dimulai dengan 'Z'. Itu bekerja seperti yang diharapkan.
Pada baris yang sama, saya menggunakan nilai maks +1 untuk int dan tipe data lainnya untuk mendapatkan pengurutan seperti yang diharapkan. Ini juga memberi saya hasil seperti yang diminta.
Namun, selalu ideal untuk mendapatkan sesuatu yang lebih mudah di mesin basis data itu sendiri yang dapat melakukan sesuatu seperti:
Seperti disebutkan dalam jawaban yang diberikan oleh a_horse_with_no_name.
sumber
Di Oracle, Anda dapat menggunakan
NULLS FIRST
atauNULLS LAST
: menetapkan bahwa nilai NULL harus dikembalikan sebelum / setelah nilai bukan NULL:Sebagai contoh:
Ref: http://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqlj13658.html
sumber
Jika Anda menggunakan MariaDB, mereka menyebutkan hal berikut dalam dokumentasi Nilai NULL .
Di atas menunjukkan dua cara untuk memesan dengan nilai NULL, Anda dapat menggabungkan ini dengan kata kunci ASC dan DESC juga. Misalnya cara lain untuk mendapatkan nilai NULL terlebih dahulu adalah:
sumber
Solusi menggunakan "case" bersifat universal, tetapi jangan gunakan indeks.
Dalam kasus saya, saya membutuhkan kinerja.
sumber
UNION ALL
.GUNAKAN fungsi NVL
Berikut adalah alternatif NVL dalam DBMS paling terkenal
sumber
sumber