Mengapa ketika kami memiliki nilai NULL dalam kolom dan kami memesan berdasarkan nilai yang naik, NULL diurutkan terlebih dahulu?
select 1 as test
union all
select 2
union all
select NULL
union all
select 3
union all
select 4
order by test
hasil dalam
NULL
1
2
3
4
Saya terus berpikir bahwa NULL berarti "Tidak Pasti" atau mungkin "Tidak Diketahui". Jika itu benar, bukankah mereka akan mengurutkan terakhir, karena nilainya bisa lebih besar dari semua nilai lainnya? (Atau ini pilihan sortir?)
Saya menggunakan SQL Server 2008R2, tetapi saya menduga ini benar di semua SQL Server, dan mungkin di semua RDBMS.
sql-server
database-theory
sorting
Richard
sumber
sumber
desc
pemesanan untuk menunjukkan hal-hal terbesar atau terbaru, dalam hal ini saya akan senang jika hal-hal nol menjadi yang terakhir.Jawaban:
NULL berarti tidak dikenal. Tidak ada interpretasi lain yang valid.
Tidak mungkin ada . Tidak ada nilai potensial . Tidak dikenal tidak diketahui tidak diketahui.
Mengenai mengapa ini muncul pertama kali, bukan yang terakhir, ini tidak dipenuhi oleh standar SQL yang dipublikasikan dan sayangnya diserahkan kepada kebijaksanaan vendor RDBMS:
sumber
Anda benar yang
NULL
dapat berarti 'Tidak Menentu' atau 'Uknownn' atau 'Belum dikenal' atau 'Tidak mendaftar'. Tetapi tidak ada alasan untuk menempatkan Nulls sebagai yang pertama atau terakhir. Jika kita tidak tahu nilai sebenarnya, maka itu bisa kecil atau besar.Saya pikir standar untuk menentukan perilaku yang diinginkan Nulls selama penyortiran, adalah:
Sayangnya SQL-Server belum mengadopsi sintaks ini. Jika saya tidak salah, PostgreSQL dan Oracle memilikinya.
Satu solusi:
Solusi lain yang perlu penyesuaian tergantung pada tipe data - tetapi tidak akan terbentuk dengan baik, karena tidak dapat menggunakan indeks pada
(test)
:sumber
Saya tidak tahu mengapa itu dilakukan seperti itu, tetapi menurut definisi NULLS tidak dapat dibandingkan dengan non-NULLS, sehingga mereka harus pergi di awal atau di akhir (jawaban Markus membahas hal ini dengan lebih detail).
Untuk mendapatkan perilaku yang Anda inginkan - Sejauh yang saya tahu tidak ada opsi penyortiran untuk menempatkan nulls terakhir, jadi Anda harus menggabungkannya dengan menggunakan kolom yang dikomputasi untuk memaksa mereka bertahan. Namun, dalam SQL Server Anda tidak dapat memesan dengan kolom yang dihitung (
CASE WHEN ...
) ketika data Anda berisi operator yang ditetapkan (UNION ALL
). Begitu:Akan bekerja untuk menyortir null yang terakhir. Jika Anda harus menggunakan
UNION
(atauEXCEPT
atauINTERSECTS
) untuk menghasilkan kumpulan data Anda, maka buang data Anda ke tabel sementara seperti di atas.sumber
Jika Anda berurusan dengan angka, Anda juga dapat menggunakan
NULL
adalah nilai serendah mungkin, oleh karena ituDESC
menempatkan mereka pada akhirnya. Sementara itu nilai-nilai bukan nol memiliki tanda terbalik sehinggaDESC
sebenarnya adalahASC
pada nilai-nilai nyata. Ini harus lebih cepat daripadaCASE
dan saya kira optimizer kueri juga dapat menggunakan indeks padatest
kolom.sumber
(- test)
.