Birisi SQL'de aşağıdaki davranışı açıklayabilir mi?
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)
Birisi SQL'de aşağıdaki davranışı açıklayabilir mi?
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)
Yanıtlar:
<>
Standart SQL-92'dir; !=
eşdeğeridir. Her ikisi NULL
de değil , değerlerin değerlendirilmesi - NULL
bir değerin yok olduğunu söylemek için bir yer tutucudur.
Bu nedenle , bu gibi durumlar için IS NULL
/ IS NOT NULL
olarak yalnızca tahmin olarak kullanabilirsiniz .
Bu davranış, SQL Server'a özgü değildir. Tüm standartlara uygun SQL lehçeleri aynı şekilde çalışır.
Not : En eğer karşılaştırmak değeri boş değil , kullanmak IS NOT NULL
ile karşılaştırmak ise, değil boş değer, kullanmak <> 'YOUR_VALUE'
. Değerimin NULL değerine eşit olup olmadığını söyleyemem, ancak değerimin NULL olup olmadığını söyleyebilirim. Değerimin NULL dışında bir şey olup olmadığını karşılaştırabilirim.
!=
anladığım kadarıyla ~ 9i'ye kadar desteklemedi , bu da birçok ANSI-92 sözdizimi getirdi. Benim inancım MySQL benzer, 4.x desteğe başlıyor.
!=
daha sonraki bir spesifikasyona alternatif olarak dahil edilmiş olabileceğini düşündürmektedir <>
. Yeni özellikler üzerinde ellerim yok, bu yüzden kesin olarak söyleyemem.
WHERE MyColumn != NULL
yoksa WHERE MyColumn = NULL
deterministik mi? Ya da başka bir deyişle, MyColumn
veritabanında nullable olsun ya da olmasın , her zaman 0 satır döndürmesi garanti edilir mi?
!=
yalnızca değerleri değerlendirdiğinden, böyle bir şey yapmanın WHERE MyColumn != 'somevalue'
NULL kayıtları döndürmeyeceği de belirtilmelidir.
NULL değeri yoktur ve bu nedenle skaler değer işleçleri kullanılarak karşılaştırılamaz.
Başka bir deyişle, hiçbir değer NULL değerine eşit olamaz (veya eşit değildir), çünkü NULL değeri yoktur.
Bu nedenle, SQL özel IS NULL ve IS NOT NULL NULL ile ilgili tahmin eder.
'a' != null
bir değer ( true
/ 1
) döndürmüyor olması bana karşı sezgisel ve zaman zaman beni yakalar gibi görünüyor ! Ben "değeri olmayan bir değer" her zaman "eşit değil" olacağını düşünürdüm, ama belki bu sadece ben?!?
SELECT * FROM MyTable WHERE coalesce(MyColumn, 'x') <> 'x'
NULL değeriyse bir sabit atayabilirsiniz, böylece sentinel değeri x için uygun bir veri türü (bu durumda bir dize / karakter) verebilirsiniz. Bu TSQL sözdizimidir, ancak Oracle ve diğer motorlar benzer özelliklere sahiptir.
Bu davranışın varsayılan (ANSI) davranış olduğunu unutmayın.
Eğer sen:
SET ANSI_NULLS OFF
http://msdn.microsoft.com/en-us/library/ms188048.aspx
Farklı sonuçlar elde edersiniz.
SET ANSI_NULLS OFF
Görünüşe göre gelecekte gidecek ...
create unique index UK_MyTable on MyTable (Column) where Column is not null
): Msdn.microsoft.com/en-us/library/cc280372.aspx
SET ANSI_NULLS
KAPALI, Eşittir (=) ve Not Eşittir (<>) karşılaştırma operatörleri ISO standardı takip etmezler. Kullanan bir SELECT deyimi, WHERE column_name = NULL
sütun_adı içinde null değerleri olan satırları döndürür. Kullanan bir SELECT deyimi WHERE column_name <> NULL
, sütunda boş olmayan değerlere sahip satırları döndürür. Ayrıca, kullanan bir SELECT deyimi WHERE column_name <> XYZ_value
XYZ_value olmayan ve NULL olmayan tüm satırları döndürür. IMHO, bu son ifade null'ların sonuçlardan çıkarılmasında biraz tuhaf görünüyor!
SQL'de, NULL
sonuçları değerlendirdiğiniz / hesapladığınız her şey BİLİNMEYEN
Bu yüzden SELECT * FROM MyTable WHERE MyColumn != NULL
ya SELECT * FROM MyTable WHERE MyColumn <> NULL
da size 0 sonuç verir.
NULL
Değerlerin kontrolü için isNull işlevi sağlanmıştır.
Ayrıca, IS
üçüncü sorguda kullandığınız gibi işleci kullanabilirsiniz .
Bu yardımcı olur umarım.
NULL için tek test NULL veya NULL DEĞİLDİR. Eşitliği test etmek saçmadır çünkü tanım gereği değerin ne olduğunu bilmez.
İşte okumak için bir wikipedia makalesi:
Kullanırız
SELECT * FROM MyTable WHERE ISNULL(MyColumn, ' ') = ' ';
MyColumn'un NULL olduğu tüm satırları veya MyColumn'un boş bir dize olduğu tüm satırları döndürmek için. Birçok "son kullanıcı" için, NULL ve boş dize sorunu, ihtiyaç ve karışıklık noktası olmayan bir ayrımdır.
Boş değerlerin diğer değerlerle veya boş değerlerle karşılaştırılamaz olmasının işlevsel ve kesintisiz nedenini görmüyorum, çünkü bunu açıkça karşılaştırabiliyor ve bağlamımızda aynı ya da değil olduklarını söyleyebiliriz. Komik. Sadece bazı mantıklı sonuçlar ve tutarlılık nedeniyle bununla sürekli uğraşmamız gerekiyor. İşlevsel değil, daha işlevsel hale getirin ve tutarlı olup olmadığına ve "evrensel mantık" a sahip olup olmadığına karar vermek için filozoflara ve bilim adamlarına bırakın. :) Birisi bunun indeksler ya da başka bir şey yüzünden olduğunu söyleyebilir, bu şeylerin değerlerle aynı null'ları desteklemek için yapılamadığından şüpheliyim. İki boş bardağı karşılaştırmakla aynı, biri asma cam, diğeri bira camı, nesne türlerini karşılaştırmıyoruz, ancak içerdikleri değerleri int ve varchar ile karşılaştırabileceğiniz gibi null ile karşılaştırıyoruz ' daha da kolay, hiçbir şey ve iki hiçliğin ortak noktası nedir, onlar aynı, ben ve sql yazan herkes tarafından açıkça karşılaştırılabilir, çünkü bazı ANSI standartları nedeniyle onları garip yollarla karşılaştırarak sürekli olarak bu mantığı kırıyoruz. Neden bizim için bunu yapmak için bilgisayar gücünü kullanmıyorsunuz ve ilgili her şey akılda tutulursa işleri yavaşlatacağından şüpheliyim. "Boş değil, hiçbir şey değil", elma değil apfel, hadi ... İşlevsel olarak arkadaşın ve burada da mantık var. Sonuçta önemli olan işlevselliktir ve null'ları bu şekilde kullanmak az ya da çok işlevsellik ve kullanım kolaylığı getirir. Daha faydalı mı? çünkü bazı ANSI standartları nedeniyle bu mantığı garip yollarla karşılaştırarak sürekli kırıyoruz. Neden bizim için bunu yapmak için bilgisayar gücünü kullanmıyorsunuz ve ilgili her şey akılda tutulursa işleri yavaşlatacağından şüpheliyim. "Boş değil, hiçbir şey değil", elma değil apfel, hadi ... İşlevsel olarak arkadaşın ve burada da mantık var. Sonuçta önemli olan işlevselliktir ve null'ları bu şekilde kullanmak az ya da çok işlevsellik ve kullanım kolaylığı getirir. Daha faydalı mı? çünkü bazı ANSI standartları nedeniyle bu mantığı garip yollarla karşılaştırarak sürekli kırıyoruz. Neden bizim için bunu yapmak için bilgisayar gücünü kullanmıyorsunuz ve ilgili her şey akılda tutulursa işleri yavaşlatacağından şüpheliyim. "Boş değil, hiçbir şey değil", elma değil apfel, hadi ... İşlevsel olarak arkadaşın ve burada da mantık var. Sonuçta önemli olan işlevselliktir ve null'ları bu şekilde kullanmak az ya da çok işlevsellik ve kullanım kolaylığı getirir. Daha faydalı mı? elma değil apfel, hadi ... İşlevsel olarak arkadaşın ve burada da bir mantık var. Sonuçta önemli olan işlevselliktir ve null'ları bu şekilde kullanmak az ya da çok işlevsellik ve kullanım kolaylığı getirir. Daha faydalı mı? elma değil apfel, hadi ... İşlevsel olarak arkadaşın ve burada da bir mantık var. Sonuçta önemli olan işlevselliktir ve null'ları bu şekilde kullanmak az ya da çok işlevsellik ve kullanım kolaylığı getirir. Daha faydalı mı?
Bu kodu düşünün:
SELECT CASE WHEN NOT (1 = null or (1 is null and null is null)) THEN 1 ELSE 0 end
Kaçınız bu kodun ne getireceğini biliyor? NOT ile veya NOT olmadan 0 döndürür. Bana göre bu fonksiyonel değildir ve kafa karıştırıcı. C # 'de olması gerektiği gibi, karşılaştırma işlemleri değer döndürür, mantıksal olarak bu da değer üretir, çünkü eğer yoksa karşılaştırılacak hiçbir şey yoktur (hiçbir şey hariç). Onlar sadece "dediler": null "ile karşılaştırıldığında" 0 "döndürürler ve bu da birçok geçici çözüm ve baş ağrısı oluşturur.
Beni buraya getiren kod:
where a != b OR (a is null and b IS not null) OR (a IS not null and b IS null)
Sadece iki alanda (nerede) farklı değerler varsa karşılaştırmak gerekir, işlev kullanabilirsiniz, ama ...
NULL Karşılaştırma işleçleri kullanılarak herhangi bir değerle karşılaştırılamaz. NULL = NULL yanlış. Null bir değer değil. IS operatörü, NULL karşılaştırmaları işlemek için özel olarak tasarlanmıştır.
null = null
yerlerde kullandığımda her zaman şaşkın insanlardan keyif aldım 1=0
. Ve şikayet ederse, bunu null != null
:) olarak değiştiririm
Eski bir soru, ancak aşağıdakiler biraz daha ayrıntı verebilir.
null
hiçbir değeri veya bilinmeyen bir değeri temsil eder. Neden bazı belirsizlikler doğurabilecek bir değer olmadığını belirtmez .
Diyelim ki böyle bir sorgu çalıştırıyorsunuz:
SELECT *
FROM orders
WHERE delivered=ordered;
yani ordered
ve delivered
tarihlerinin aynı olduğu satırları arıyorsunuz .
Bir veya iki sütun boş olduğunda ne beklenir?
Tarihlerden en az biri bilinmiyor olduğundan, 2 tarihin aynı olduğunu söyleyemezsiniz. Bu, her iki tarihin de bilinmediği durumdur : ne olduklarını bilmiyorsak bile nasıl olabilirler?
Bu nedenle, null
değer olarak davranan herhangi bir ifade başarısız olmalıdır. Bu durumda, eşleşmez. Aşağıdakileri denerseniz bu da geçerlidir:
SELECT *
FROM orders
WHERE delivered<>ordered;
Yine, nasıl iki değer olduğunu söyleyebiliriz değil ne olduklarını bilmiyorsanız aynı.
SQL'in eksik değerler için belirli bir testi vardır:
IS NULL
Özellikle değerleri karşılaştırmak değil , eksik değerleri arar .
Son olarak, !=
operatör ile ilgili olarak, bildiğim kadarıyla, aslında standartların hiçbirinde değildir, ancak çok geniş bir şekilde desteklenmektedir. Bazı dillerdeki programcıların kendilerini evlerinde daha fazla hissetmelerini sağlamak için eklendi. Açıkçası, bir programcı hangi dili kullandıklarını hatırlamakta zorlanıyorsa, kötü bir başlangıç yapıyorlar.
NULL
ile karşılaştırdığımızda, değeri bir NULL
değerin " bir değere sahip" ile karşılaştırdığımızı , değeri "alt öğenin NULL
¿sahip olduğu belirsiz değere ?" değil, "ki bunu kesinlikle bilemeyiz. Bu gerçekten işleri kolaylaştırır.
IS NULL
çok daha zahmetli olduğundan emin değilim = NULL
. Bence , ikincisine özel bir durum olarak davranmak yerine WHERE columnA = columnB
, aynı yorumda bulunmanın daha tutarlı olacağını düşünüyorum WHERE columnA = NULL
. Unutmayın NULL
olduğu değil bir değer. O programlama dilleri olarak ise test etmek için meşru variable == null
çünkü öyle null
farklı bir anlamı vardır; bilinmeyen bir şeyi değil, bir değerin kasıtlı olarak sıfırlanmasını temsil eder. SQL ile öyle değil.
IS NULL
AND =NULL
arasında ek yük olmadığına katılıyorum . Ama Hover'ın sonuncusuna bir bakın. Tekrar tekrar deneyimlemekten bıktım, bir sürü of gereksiz yapmak zorunda mıyım? ekstra kontrol ...
Her ne kadar (sipariş önemli olmasa da) i
yeni bir değer d
olmak ve eski olmak bir değerde bir değişiklik olup olmadığını bulmak için yapılan bu kodu önermek istiyorum
. Bu nedenle, değerden null'a veya tersi bir değişiklik bir değişikliktir, ancak null'den null'e (elbette, değerden başka bir değere bir değişikliktir, değerden aynı değildir).
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
Bu işlevi kullanmak için şunları yapabilirsiniz:
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
Sonuçlar:
---- 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
Sql_variant kullanımı onu çeşitli tipler için uyumlu hale getirir
NULL hiçbir şey değil ... bilinmiyor. NULL hiçbir şeye eşit değildir. Bu nedenle, SQL sorgularınızda = NULL yerine IS NULL sihirli ifadesini kullanmanız gerekir
Buna başvurabilirsiniz: http://weblogs.sqlteam.com/markc/archive/2009/06/08/60929.aspx
<>
92 spesifikasyonda olduğuna inanıyorum, ancak çoğu satıcı destekliyor!=
ve / veya 99 veya 03 gibi daha sonraki bir spesifikasyona dahil ediliyor.