Czy ktoś mógłby wyjaśnić następujące zachowanie w 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)
Czy ktoś mógłby wyjaśnić następujące zachowanie w 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)
Odpowiedzi:
<>to Standard SQL-92; !=jest jego odpowiednikiem. Oba oceniają wartości, które NULLnie są - NULLjest symbolem zastępczym, który mówi, że nie ma wartości.
Dlatego możesz używać IS NULL/ IS NOT NULLjako predykatów tylko w takich sytuacjach.
To zachowanie nie jest specyficzne dla SQL Server. Wszystkie dialekty SQL zgodne ze standardami działają w ten sam sposób.
Uwaga : Aby porównać, jeśli twoja wartość nie jest równa null , użyj IS NOT NULL, natomiast do porównania z wartością inną niż null , użyj <> 'YOUR_VALUE'. Nie mogę powiedzieć, czy moja wartość jest równa NULL, ale mogę powiedzieć, czy moja wartość to NULL, czy NIE NULL. Mogę porównać, jeśli moja wartość jest inna niż NULL.
!=aż ~ 9i, jak rozumiem, co przyniosło wiele składni ANSI-92. Wierzę, że MySQL jest podobny, zaczynając wsparcie w 4.x.
!=mógł zostać włączony do późniejszej specyfikacji jako alternatywa dla <>. Nie mam nowych specyfikacji, więc nie mogę być tego pewien.
WHERE MyColumn != NULLlub WHERE MyColumn = NULLdeterministyczny? Innymi słowy, czy gwarantuje, że zawsze zwróci 0 wierszy, bez względu na MyColumnto, czy w bazie danych jest dopuszczalna wartość null?
!=tylko ocenia wartości, zrobienie czegoś podobnego WHERE MyColumn != 'somevalue'nie zwróci rekordów NULL.
Wartość NULL nie ma wartości, dlatego nie można jej porównywać za pomocą operatorów wartości skalarnych.
Innymi słowy, żadna wartość nigdy nie może być równa (lub nie być równa) NULL, ponieważ NULL nie ma żadnej wartości.
Dlatego SQL ma specjalne predykaty IS NULL i IS NOT NULL do obsługi NULL.
'a' != nullNIE zwracanie wartości ( true/ 1) jest sprzeczne z intuicją i od czasu do czasu mnie łapie! Myślałem, że „pewna wartość w porównaniu do żadnej wartości” zawsze będzie „nie równa”, ale może to tylko ja?!?
SELECT * FROM MyTable WHERE coalesce(MyColumn, 'x') <> 'x'można przypisać stałą, jeśli jest to NULL, pod warunkiem, że podasz odpowiedni typ danych dla wartości wartownika x (w tym przypadku ciąg / char). Jest to składnia TSQL, ale Oracle i inne silniki mają podobne funkcje.
Należy pamiętać, że takie zachowanie jest zachowaniem domyślnym (ANSI).
Jeśli ty:
SET ANSI_NULLS OFF
http://msdn.microsoft.com/en-us/library/ms188048.aspx
Otrzymasz różne wyniki.
SET ANSI_NULLS OFF najwyraźniej odejdzie w przyszłości ...
create unique index UK_MyTable on MyTable (Column) where Column is not null): Msdn.microsoft.com/en-us/library/cc280372.aspx
SET ANSI_NULLSjest wyłączona, operatory porównania równe (=) i nierówne (<>) nie są zgodne ze standardem ISO. Instrukcja SELECT, która używa, WHERE column_name = NULLzwraca wiersze o wartości null w kolumnie nazwa_kolumny. WHERE column_name <> NULLUżyta instrukcja SELECT zwraca wiersze, które mają niepuste wartości w kolumnie. Ponadto instrukcja SELECT, która używa, WHERE column_name <> XYZ_valuezwraca wszystkie wiersze, które nie są wartościami XYZ i które nie mają wartości NULL. IMHO, to ostatnie stwierdzenie wydaje się trochę dziwne, ponieważ wyklucza wartości zerowe z wyników!
W SQL wszystko oceniasz / obliczasz z NULLwynikami w NIEZNANY
Dlatego SELECT * FROM MyTable WHERE MyColumn != NULLlub SELECT * FROM MyTable WHERE MyColumn <> NULLdaje 0 wyników.
Aby zapewnić sprawdzanie NULLwartości, zapewniona jest funkcja isNull.
Ponadto możesz użyć ISoperatora, tak jak w trzecim zapytaniu.
Mam nadzieję że to pomoże.
Jedyny test na wartość NULL to IS NULL lub IS NOT NULL. Testowanie równości jest nonsensowne, ponieważ z definicji nie wiadomo, jaka jest wartość.
Oto artykuł w Wikipedii do przeczytania:
Używamy
SELECT * FROM MyTable WHERE ISNULL(MyColumn, ' ') = ' ';
aby zwrócić wszystkie wiersze, w których MyColumn ma wartość NULL lub wszystkie wiersze, w których MyColumn jest pustym ciągiem. Dla wielu „użytkowników końcowych” kwestia NULL vs. pusty ciąg znaków jest rozróżnieniem bez potrzeby i zamieszania.
Po prostu nie widzę funkcjonalnego i bezproblemowego powodu, dla którego wartości zerowe nie są porównywalne z innymi wartościami lub innymi wartościami zerowymi, ponieważ możemy je wyraźnie porównać i powiedzieć, że są takie same lub nie w naszym kontekście. To jest zabawne. Właśnie z powodu pewnych logicznych wniosków i konsekwencji musimy stale się tym przejmować. Nie działa, uczyń go bardziej funkcjonalnym i pozostaw filozofom i naukowcom do stwierdzenia, czy jest spójny czy nie, i czy zawiera „uniwersalną logikę”. :) Ktoś może powiedzieć, że to z powodu indeksów lub czegoś innego, wątpię, aby te rzeczy nie mogły być obsługiwane przez wartości zerowe takie same jak wartości. To tak samo, jak porównywanie dwóch pustych kieliszków, jedna to kieliszek do wina, a druga to kufel do piwa, nie porównujemy typów obiektów, ale wartości, które zawierają, tak samo jak można porównać int i varchar, z null it ” jeszcze łatwiej, to nic i to, co łączy ze sobą dwie nicość, są takie same, wyraźnie porównywalne przeze mnie i przez wszystkich innych, którzy piszą sql, ponieważ ciągle łamiemy tę logikę, porównując je w dziwny sposób ze względu na niektóre standardy ANSI. Dlaczego nie skorzystać z mocy komputera, aby zrobić to za nas i wątpię, że spowolniłoby to wszystko, gdyby wszystko związane z tym zostało skonstruowane z myślą o tym. „To nie jest zero, to nic”, to nie jest jabłko, to jest apfel, daj spokój ... Funkcjonalnie jest twoim przyjacielem i jest tu również logika. Ostatecznie jedyną rzeczą, która ma znaczenie, jest funkcjonalność i używanie zer w ten sposób zapewnia mniej więcej funkcjonalność i łatwość użycia. Czy to jest bardziej przydatne? ponieważ ciągle łamiemy tę logikę, porównując je w dziwny sposób z powodu niektórych standardów ANSI. Dlaczego nie skorzystać z mocy komputera, aby zrobić to za nas i wątpię, że spowolniłoby to wszystko, gdyby wszystko związane z tym zostało skonstruowane z myślą o tym. „To nie jest zero, to nic”, to nie jest jabłko, to jest apfel, daj spokój ... Funkcjonalnie jest twoim przyjacielem i jest tu również logika. Ostatecznie jedyną rzeczą, która ma znaczenie, jest funkcjonalność i używanie zer w ten sposób zapewnia mniej więcej funkcjonalność i łatwość użycia. Czy to jest bardziej przydatne? ponieważ ciągle łamiemy tę logikę, porównując je w dziwny sposób z powodu niektórych standardów ANSI. Dlaczego nie skorzystać z mocy komputera, aby zrobić to za nas i wątpię, że spowolniłoby to wszystko, gdyby wszystko związane z tym zostało skonstruowane z myślą o tym. „To nie jest zero, to nic”, to nie jest jabłko, to jest apfel, daj spokój ... Funkcjonalnie jest twoim przyjacielem i jest tu również logika. Ostatecznie jedyną rzeczą, która ma znaczenie, jest funkcjonalność i używanie zer w ten sposób zapewnia mniej więcej funkcjonalność i łatwość użycia. Czy to jest bardziej przydatne? to nie jabłko, to apfel, daj spokój ... Funkcjonalnie jest twoim przyjacielem i tutaj też jest logika. Ostatecznie jedyną rzeczą, która ma znaczenie, jest funkcjonalność i używanie zer w ten sposób zapewnia mniej więcej funkcjonalność i łatwość użycia. Czy to jest bardziej przydatne? to nie jabłko, to apfel, daj spokój ... Funkcjonalnie jest twoim przyjacielem i tutaj też jest logika. Ostatecznie jedyną rzeczą, która ma znaczenie, jest funkcjonalność i używanie zer w ten sposób zapewnia mniej więcej funkcjonalność i łatwość użycia. Czy to jest bardziej przydatne?
Rozważ ten kod:
SELECT CASE WHEN NOT (1 = null or (1 is null and null is null)) THEN 1 ELSE 0 end
Ilu z was wie, co zwróci ten kod? Z lub bez NOT zwraca 0. Dla mnie to nie działa i jest mylące. W c # wszystko jest tak, jak powinno być, operacje porównywania zwracają wartość, logicznie to też tworzy wartość, ponieważ jeśli nie, nie ma nic do porównania (oprócz. Nic :)). Po prostu „powiedzieli”: cokolwiek w porównaniu do null „zwraca” 0, co stwarza wiele obejść i bólów głowy.
Oto kod, który mnie tu przyprowadził:
where a != b OR (a is null and b IS not null) OR (a IS not null and b IS null)
Muszę tylko porównać, jeśli dwa pola (gdzie) mają różne wartości, mógłbym użyć funkcji, ale ...
NULL Nie można porównać do żadnej wartości za pomocą operatorów porównania. NULL = NULL jest fałszem. Null nie jest wartością. Operator IS jest specjalnie zaprojektowany do obsługi porównań NULL.
null = nullco można wykorzystać 1=0w zapytaniu ad hoc. A jeśli narzekają, zmieniam na null != null:)
Stare pytanie, ale poniższe mogą zawierać więcej szczegółów.
nulloznacza brak wartości lub nieznaną wartość. Nie określa, dlaczego nie ma wartości, co może prowadzić do niejasności.
Załóżmy, że uruchamiasz takie zapytanie:
SELECT *
FROM orders
WHERE delivered=ordered;
oznacza to, że szukasz wierszy, w których daty orderedi deliveredsą takie same.
Czego można się spodziewać, gdy jedna lub obie kolumny są puste?
Ponieważ co najmniej jedna z dat jest nieznana, nie można oczekiwać, że obie daty będą takie same. Jest tak również w przypadku, gdy oba daty są nieznane: jak mogą być takie same, jeśli nawet nie wiemy, jakie są?
Z tego powodu każde wyrażenie traktowane nulljako wartość musi zawieść. W takim przypadku nie będzie pasować. Dzieje się tak również wtedy, gdy spróbujesz:
SELECT *
FROM orders
WHERE delivered<>ordered;
Ponownie, jak możemy powiedzieć, że dwie wartości nie są takie same, jeśli nie wiemy, czym one są.
SQL ma specyficzny test na brakujące wartości:
IS NULL
W szczególności nie porównuje wartości, ale szuka brakujących wartości.
Wreszcie, jeśli chodzi o !=operatora, o ile mi wiadomo, nie jest on faktycznie objęty żadnym ze standardów, ale jest bardzo szeroko wspierany. Zostało dodane, aby programiści z niektórych języków czuli się bardziej jak w domu. Szczerze mówiąc, jeśli programista ma trudności z zapamiętaniem używanego języka, zaczyna się źle.
NULLmamy na myśli, że porównujemy wartość z „posiadaniem NULLwartości”, a nie z wartością „nieokreślonej wartości, jaką NULLma podkład ”? ale której nie wiemy ”, o którym oczywiście nigdy nie będziemy wiedzieć. To naprawdę by to ułatwiło.
IS NULLjest o wiele bardziej uciążliwe niż pisanie = NULL. Myślę, że byłoby bardziej spójne, gdyby WHERE columnA = columnBmiało taką samą interpretację WHERE columnA = NULL, niż traktować tę ostatnią jako szczególny przypadek. Pamiętaj, że NULLto nie jest wartość. W języków programowania, gdzie to jest uzasadnione, aby przetestować variable == nullto dlatego, że nullma inne znaczenie; nie reprezentuje czegoś nieznanego, ale celowe resetowanie wartości. Nie w przypadku SQL.
IS NULLAND =NULL. Ale spójrz na ostatni Hover. Mam dość ciągłego doświadczania tego, że muszę robić mnóstwo niepotrzebnych? dodatkowe sprawdzanie ...
Chciałbym zasugerować ten kod, który stworzyłem, aby sprawdzić, czy nastąpiła zmiana wartości,
ibędąc nową wartością i dbędąc starą (chociaż kolejność nie ma znaczenia). Z tego powodu zmiana z wartości na null lub odwrotnie jest zmianą, ale z null na null nie jest (oczywiście, od wartości do innej wartości jest zmianą, ale od wartości do tej samej nie jest).
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
Aby skorzystać z tej funkcji, możesz
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
Wyniki są następujące:
---- 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
Zastosowanie sql_variant sprawia, że jest on kompatybilny z różnymi typami
NULL to nic ... nie jest znane. NULL nic nie równa. Dlatego w zapytaniach SQL musisz używać magicznej frazy IS NULL zamiast = NULL
Możesz to odnieść: http://weblogs.sqlteam.com/markc/archive/2009/06/08/60929.aspx
<>tak jest w specyfikacji 92, ale większość dostawców obsługuje!=i / lub jest uwzględniona w późniejszej specyfikacji, np. 99 lub 03.