Bisakah seseorang tolong jelaskan perilaku berikut dalam SQL?
SELECT * FROM MyTable WHERE MyColumn != NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn <> NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn IS NOT NULL (568 Results)
Bisakah seseorang tolong jelaskan perilaku berikut dalam SQL?
SELECT * FROM MyTable WHERE MyColumn != NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn <> NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn IS NOT NULL (568 Results)
Jawaban:
<>
adalah Standard SQL-92; !=
adalah padanannya. Keduanya mengevaluasi nilai-nilai, yang NULL
bukan - NULL
adalah pengganti yang mengatakan bahwa tidak ada nilai.
Itulah sebabnya Anda hanya dapat menggunakan IS NULL
/ IS NOT NULL
sebagai predikat untuk situasi seperti itu.
Perilaku ini tidak spesifik untuk SQL Server. Semua dialek SQL yang memenuhi standar bekerja dengan cara yang sama.
Catatan : Untuk membandingkan jika nilai Anda bukan nol , Anda menggunakan IS NOT NULL
, sedangkan untuk membandingkan dengan bukan nilai nol , Anda gunakan <> 'YOUR_VALUE'
. Saya tidak bisa mengatakan apakah nilai saya sama atau tidak sama dengan NULL, tetapi saya dapat mengatakan apakah nilai saya NULL atau NOT NULL. Saya dapat membandingkan jika nilai saya adalah sesuatu selain NULL.
!=
sampai ~ 9 seperti yang saya mengerti, yang membawa banyak sintaks ANSI-92. Keyakinan saya adalah MySQL serupa, memulai dukungan di 4.x.
!=
mungkin telah dimasukkan dalam spesifikasi nanti sebagai alternatif <>
. Tidak punya spesifikasi baru jadi saya tidak bisa mengatakannya dengan pasti.
WHERE MyColumn != NULL
atau WHERE MyColumn = NULL
deterministik? Atau dengan kata lain, apakah dijamin untuk selalu mengembalikan 0 baris, tidak peduli apakah MyColumn
itu dapat dibatalkan dalam database atau tidak?
!=
hanya mengevaluasi nilai-nilai, melakukan sesuatu seperti WHERE MyColumn != 'somevalue'
tidak akan mengembalikan catatan NULL.
NULL tidak memiliki nilai, sehingga tidak dapat dibandingkan dengan menggunakan operator nilai skalar.
Dengan kata lain, tidak ada nilai yang dapat sama dengan (atau tidak sama dengan) NULL karena NULL tidak memiliki nilai.
Oleh karena itu, SQL memiliki predikat IS NULL dan IS NOT NULL untuk berurusan dengan NULL.
'a' != null
TIDAK mengembalikan nilai ( true
/ 1
) berlawanan dengan intuisi dan menarik saya keluar dari waktu ke waktu! Saya akan berpikir "nilai dibandingkan dengan tidak ada nilai" akan selalu "tidak sama", tapi mungkin itu hanya saya?!?
SELECT * FROM MyTable WHERE coalesce(MyColumn, 'x') <> 'x'
dapat menetapkan konstanta jika nilai NULL, asalkan Anda memberikan tipe data yang sesuai untuk nilai sentinel x (dalam hal ini string / char). Ini adalah sintaks TSQL tetapi Oracle dan mesin lainnya memiliki fitur serupa.
Perhatikan bahwa perilaku ini adalah perilaku default (ANSI).
Jika kamu:
SET ANSI_NULLS OFF
http://msdn.microsoft.com/en-us/library/ms188048.aspx
Anda akan mendapatkan hasil yang berbeda.
SET ANSI_NULLS OFF
tampaknya akan pergi di masa depan ...
create unique index UK_MyTable on MyTable (Column) where Column is not null
): msdn.microsoft.com/en-us/library/cc280372.aspx
SET ANSI_NULLS
MATI, operator pembanding Equals (=) dan Not Equal To (<>) tidak mengikuti standar ISO. Pernyataan SELECT yang menggunakan WHERE column_name = NULL
mengembalikan baris yang memiliki nilai nol dalam nama_kolom. Pernyataan SELECT yang menggunakan WHERE column_name <> NULL
mengembalikan baris yang memiliki nilai nonnull di kolom. Juga, pernyataan SELECT yang menggunakan WHERE column_name <> XYZ_value
mengembalikan semua baris yang bukan XYZ_value dan yang bukan NULL. IMHO, pernyataan terakhir ini tampaknya sedikit aneh karena tidak menyertakan null dari hasilnya!
Dalam SQL, apa pun yang Anda evaluasi / hitung dengan NULL
hasil ke UNKNOWN
Inilah sebabnya SELECT * FROM MyTable WHERE MyColumn != NULL
atau SELECT * FROM MyTable WHERE MyColumn <> NULL
memberi Anda 0 hasil.
Untuk memberikan pemeriksaan NULL
nilai, fungsi isNull disediakan.
Selain itu, Anda bisa menggunakan IS
operator seperti yang Anda gunakan dalam kueri ketiga.
Semoga ini membantu.
Satu-satunya tes untuk NULL adalah IS NULL atau IS NOT NULL. Pengujian untuk kesetaraan tidak masuk akal karena menurut definisi orang tidak tahu apa nilainya.
Inilah artikel wikipedia untuk dibaca:
Kita gunakan
SELECT * FROM MyTable WHERE ISNULL(MyColumn, ' ') = ' ';
untuk mengembalikan semua baris di mana MyColumn adalah NULL atau semua baris di mana MyColumn adalah string kosong. Bagi banyak "pengguna akhir", masalah NULL vs string kosong adalah perbedaan tanpa perlu dan titik kebingungan.
Saya hanya tidak melihat alasan fungsional dan mulus untuk null tidak dapat dibandingkan dengan nilai-nilai lain atau null lainnya, karena kita dapat dengan jelas membandingkannya dan mengatakan mereka sama atau tidak dalam konteks kita. Itu lucu. Hanya karena beberapa kesimpulan dan konsistensi logis kita perlu terus-menerus peduli dengannya. Itu tidak fungsional, membuatnya lebih fungsional dan serahkan kepada para filsuf dan ilmuwan untuk menyimpulkan apakah itu konsisten atau tidak dan apakah itu memegang "logika universal". :) Seseorang mungkin mengatakan itu karena indeks atau sesuatu yang lain, saya ragu bahwa hal-hal itu tidak dapat dibuat untuk mendukung nol sama dengan nilai. Ini sama dengan membandingkan dua gelas kosong, satu adalah gelas anggur dan lainnya adalah gelas bir, kami tidak membandingkan jenis objek tetapi nilai-nilai yang dikandungnya, sama seperti Anda dapat membandingkan int dan varchar, dengan nol itu ' Bahkan lebih mudah, itu bukan apa-apa dan apa yang sama-sama dimiliki oleh ketiadaan, keduanya sama, jelas dapat dibandingkan oleh saya dan semua orang yang menulis sql, karena kami terus-menerus memecahkan logika itu dengan membandingkannya dengan cara yang aneh karena beberapa standar ANSI. Mengapa tidak menggunakan daya komputer untuk melakukannya untuk kita dan saya ragu itu akan memperlambat segalanya jika semuanya terkait dibangun dengan itu dalam pikiran. "Ini bukan nol itu bukan apa-apa", itu bukan apel itu apfel, ayolah ... Secara fungsional adalah teman Anda dan ada juga logika di sini. Pada akhirnya satu-satunya hal yang penting adalah fungsionalitas dan tidak menggunakan null dengan cara itu membawa fungsionalitas yang lebih atau kurang dan kemudahan penggunaan. Apakah ini lebih bermanfaat? karena kami terus-menerus melanggar logika itu dengan membandingkannya dengan cara yang aneh karena beberapa standar ANSI. Mengapa tidak menggunakan daya komputer untuk melakukannya untuk kita dan saya ragu itu akan memperlambat segalanya jika semuanya terkait dibangun dengan itu dalam pikiran. "Ini bukan nol itu bukan apa-apa", itu bukan apel itu apfel, ayolah ... Secara fungsional adalah teman Anda dan ada juga logika di sini. Pada akhirnya satu-satunya hal yang penting adalah fungsionalitas dan tidak menggunakan null dengan cara itu membawa fungsionalitas yang lebih atau kurang dan kemudahan penggunaan. Apakah ini lebih bermanfaat? karena kami terus-menerus melanggar logika itu dengan membandingkannya dengan cara yang aneh karena beberapa standar ANSI. Mengapa tidak menggunakan daya komputer untuk melakukannya untuk kita dan saya ragu itu akan memperlambat segalanya jika semuanya terkait dibangun dengan itu dalam pikiran. "Ini bukan nol itu bukan apa-apa", itu bukan apel itu apfel, ayolah ... Secara fungsional adalah teman Anda dan ada juga logika di sini. Pada akhirnya satu-satunya hal yang penting adalah fungsionalitas dan tidak menggunakan null dengan cara itu membawa fungsionalitas yang lebih atau kurang dan kemudahan penggunaan. Apakah ini lebih bermanfaat? Bukan apel itu apfel, ayolah ... Secara fungsional adalah teman Anda dan ada juga logika di sini. Pada akhirnya satu-satunya hal yang penting adalah fungsionalitas dan tidak menggunakan null dengan cara itu membawa fungsionalitas yang lebih atau kurang dan kemudahan penggunaan. Apakah ini lebih bermanfaat? Bukan apel itu apfel, ayolah ... Secara fungsional adalah teman Anda dan ada juga logika di sini. Pada akhirnya satu-satunya hal yang penting adalah fungsionalitas dan tidak menggunakan null dengan cara itu membawa fungsionalitas yang lebih atau kurang dan kemudahan penggunaan. Apakah ini lebih bermanfaat?
Pertimbangkan kode ini:
SELECT CASE WHEN NOT (1 = null or (1 is null and null is null)) THEN 1 ELSE 0 end
Berapa banyak dari Anda yang tahu kode apa yang akan dikembalikan? Dengan atau tanpa TIDAK mengembalikan 0. Bagi saya itu tidak berfungsi dan itu membingungkan. Dalam c # itu semua sebagaimana mestinya, operasi perbandingan mengembalikan nilai, secara logis ini juga menghasilkan nilai, karena jika tidak ada yang bisa dibandingkan (kecuali. Tidak ada :)). Mereka hanya "berkata": apa pun yang dibandingkan dengan nol "mengembalikan" 0 dan itu menciptakan banyak solusi dan sakit kepala.
Ini adalah kode yang membawaku ke sini:
where a != b OR (a is null and b IS not null) OR (a IS not null and b IS null)
Saya hanya perlu membandingkan jika dua bidang (di mana) memiliki nilai yang berbeda, saya bisa menggunakan fungsi, tapi ...
NULL Tidak dapat dibandingkan dengan nilai apa pun menggunakan operator pembanding. NULL = NULL salah. Null bukan nilai. Operator IS dirancang khusus untuk menangani perbandingan NULL.
null = null
mana orang mungkin menggunakan 1=0
beberapa permintaan khusus. Dan jika mereka mengeluh, saya ubah ke null != null
:)
Pertanyaan lama, tetapi berikut ini mungkin menawarkan beberapa detail.
null
mewakili tidak ada nilai atau nilai yang tidak diketahui. Itu tidak menentukan mengapa tidak ada nilai, yang dapat menyebabkan ambiguitas.
Misalkan Anda menjalankan kueri seperti ini:
SELECT *
FROM orders
WHERE delivered=ordered;
yaitu, Anda mencari baris di mana tanggal ordered
dan delivered
adalah sama.
Apa yang diharapkan ketika satu atau kedua kolom adalah nol?
Karena setidaknya salah satu tanggal tidak diketahui, Anda tidak dapat berharap untuk mengatakan bahwa 2 tanggal itu sama. Ini juga kasus ketika kedua tanggal tidak diketahui: bagaimana mereka bisa sama jika kita bahkan tidak tahu apa itu?
Karena alasan ini, ekspresi apa pun yang memperlakukan null
sebagai nilai harus gagal. Dalam hal ini, itu tidak akan cocok. Ini juga terjadi jika Anda mencoba yang berikut:
SELECT *
FROM orders
WHERE delivered<>ordered;
Sekali lagi, bagaimana kita dapat mengatakan bahwa dua nilai tidak sama jika kita tidak tahu apa itu nilai.
SQL memiliki tes khusus untuk nilai yang hilang:
IS NULL
Secara khusus ini tidak membandingkan nilai, tetapi mencari nilai yang hilang .
Akhirnya, berkenaan dengan !=
operator, sejauh yang saya ketahui, itu sebenarnya tidak ada dalam standar, tetapi didukung secara luas. Itu ditambahkan untuk membuat programmer dari beberapa bahasa merasa lebih di rumah. Terus terang, jika seorang programmer mengalami kesulitan mengingat bahasa apa yang mereka gunakan, mereka memulai dengan buruk.
NULL
kita berarti bahwa kita membandingkan nilai dengan 'memiliki NULL
nilai', bukan nilai untuk "nilai yang tidak ditentukan bahwa yang mendasari NULL
adalah ¿memiliki? tetapi kita tidak tahu ", yang jelas kita tidak akan pernah bisa tahu. Itu akan sangat memudahkan.
IS NULL
jauh lebih sulit daripada menulis = NULL
. Saya pikir akan lebih konsisten jika WHERE columnA = columnB
memiliki interpretasi yang sama dengan WHERE columnA = NULL
, daripada memperlakukan yang terakhir sebagai kasus khusus. Ingat bahwa NULL
ini bukan nilai. Dalam bahasa pemrograman mana yang sah untuk mengujinya variable == null
adalah karena null
memiliki makna yang berbeda; itu tidak mewakili sesuatu yang tidak diketahui, tetapi pengaturan ulang suatu nilai secara sengaja. Tidak demikian halnya dengan SQL.
IS NULL
AND =NULL
dalam contoh terbaru Anda. Tapi lihat yang terakhir melayang-layang. Saya lelah mengalaminya lagi dan lagi, harus melakukan banyak ¿yang tidak perlu? pemeriksaan ekstra ...
Saya ingin menyarankan kode ini saya buat untuk menemukan jika ada perubahan nilai,
i
menjadi nilai baru dan d
menjadi yang lama (meskipun urutannya tidak masalah). Dalam hal ini, perubahan dari nilai ke nol atau sebaliknya adalah perubahan tetapi dari nol ke nol tidak (tentu saja, dari nilai ke nilai lain adalah perubahan tetapi dari nilai ke nilai yang sama tidak).
CREATE FUNCTION [dbo].[ufn_equal_with_nulls]
(
@i sql_variant,
@d sql_variant
)
RETURNS bit
AS
BEGIN
DECLARE @in bit = 0, @dn bit = 0
if @i is null set @in = 1
if @d is null set @dn = 1
if @in <> @dn
return 0
if @in = 1 and @dn = 1
return 1
if @in = 0 and @dn = 0 and @i = @d
return 1
return 0
END
Untuk menggunakan fungsi ini, Anda bisa
declare @tmp table (a int, b int)
insert into @tmp values
(1,1),
(1,2),
(1,null),
(null,1),
(null,null)
---- in select ----
select *, [dbo].[ufn_equal_with_nulls](a,b) as [=] from @tmp
---- where equal ----
select *,'equal' as [Predicate] from @tmp where [dbo].[ufn_equal_with_nulls](a,b) = 1
---- where not equal ----
select *,'not equal' as [Predicate] from @tmp where [dbo].[ufn_equal_with_nulls](a,b) = 0
Hasilnya adalah:
---- in select ----
a b =
1 1 1
1 2 0
1 NULL 0
NULL 1 0
NULL NULL 1
---- where equal ----
1 1 equal
NULL NULL equal
---- where not equal ----
1 2 not equal
1 NULL not equal
NULL 1 not equal
Penggunaan sql_variant membuatnya kompatibel untuk berbagai jenis
NULL bukanlah apa-apa ... tidak diketahui. NULL tidak sama dengan apa pun. Itu sebabnya Anda harus menggunakan frase ajaib IS NULL alih-alih = NULL dalam kueri SQL Anda
Anda dapat merujuk ini: http://weblogs.sqlteam.com/markc/archive/2009/06/08/60929.aspx
<>
bahwa itu ada dalam spesifikasi 92 tetapi kebanyakan vendor mendukung!=
dan / atau itu termasuk dalam spesifikasi berikutnya seperti 99 atau 03.