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 NULLbukan - NULLadalah pengganti yang mengatakan bahwa tidak ada nilai.
Itulah sebabnya Anda hanya dapat menggunakan IS NULL/ IS NOT NULLsebagai 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 != NULLatau WHERE MyColumn = NULLdeterministik? Atau dengan kata lain, apakah dijamin untuk selalu mengembalikan 0 baris, tidak peduli apakah MyColumnitu 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' != nullTIDAK 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_NULLSMATI, operator pembanding Equals (=) dan Not Equal To (<>) tidak mengikuti standar ISO. Pernyataan SELECT yang menggunakan WHERE column_name = NULLmengembalikan baris yang memiliki nilai nol dalam nama_kolom. Pernyataan SELECT yang menggunakan WHERE column_name <> NULLmengembalikan baris yang memiliki nilai nonnull di kolom. Juga, pernyataan SELECT yang menggunakan WHERE column_name <> XYZ_valuemengembalikan 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 NULLhasil ke UNKNOWN
Inilah sebabnya SELECT * FROM MyTable WHERE MyColumn != NULLatau SELECT * FROM MyTable WHERE MyColumn <> NULLmemberi Anda 0 hasil.
Untuk memberikan pemeriksaan NULLnilai, fungsi isNull disediakan.
Selain itu, Anda bisa menggunakan ISoperator 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 = nullmana orang mungkin menggunakan 1=0beberapa permintaan khusus. Dan jika mereka mengeluh, saya ubah ke null != null:)
Pertanyaan lama, tetapi berikut ini mungkin menawarkan beberapa detail.
nullmewakili 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 ordereddan deliveredadalah 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 nullsebagai 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.
NULLkita berarti bahwa kita membandingkan nilai dengan 'memiliki NULLnilai', bukan nilai untuk "nilai yang tidak ditentukan bahwa yang mendasari NULLadalah ¿memiliki? tetapi kita tidak tahu ", yang jelas kita tidak akan pernah bisa tahu. Itu akan sangat memudahkan.
IS NULLjauh lebih sulit daripada menulis = NULL. Saya pikir akan lebih konsisten jika WHERE columnA = columnBmemiliki interpretasi yang sama dengan WHERE columnA = NULL, daripada memperlakukan yang terakhir sebagai kasus khusus. Ingat bahwa NULLini bukan nilai. Dalam bahasa pemrograman mana yang sah untuk mengujinya variable == nulladalah karena nullmemiliki makna yang berbeda; itu tidak mewakili sesuatu yang tidak diketahui, tetapi pengaturan ulang suatu nilai secara sengaja. Tidak demikian halnya dengan SQL.
IS NULLAND =NULLdalam 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,
imenjadi nilai baru dan dmenjadi 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.