Könnte jemand bitte das folgende Verhalten in SQL erklären?
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)
Könnte jemand bitte das folgende Verhalten in SQL erklären?
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)
Antworten:
<>
ist Standard SQL-92; !=
ist das Äquivalent. Beide bewerten nach Werten, was NULL
nicht - NULL
ist ein Platzhalter, um zu sagen, dass kein Wert vorhanden ist.
Deshalb können Sie IS NULL
/ nur IS NOT NULL
als Prädikate für solche Situationen verwenden.
Dieses Verhalten ist nicht spezifisch für SQL Server. Alle standardkonformen SQL-Dialekte funktionieren auf die gleiche Weise.
Hinweis : Zum Vergleichen, wenn Ihr Wert nicht null ist , verwenden Sie IS NOT NULL
, während Sie zum Vergleichen mit dem Wert nicht null verwenden <> 'YOUR_VALUE'
. Ich kann nicht sagen, ob mein Wert gleich oder nicht gleich NULL ist, aber ich kann sagen, ob mein Wert NULL oder NICHT NULL ist. Ich kann vergleichen, ob mein Wert etwas anderes als NULL ist.
!=
wie ich verstehe, bis ~ 9i nicht unterstützt , was eine Menge ANSI-92-Syntax mit sich brachte. Meiner Meinung nach ist MySQL ähnlich und startet die Unterstützung in 4.x.
!=
dies in einer späteren Spezifikation als Alternative zu enthalten sein könnte <>
. Ich habe keine neuen Spezifikationen in den Händen, daher kann ich nicht sicher sagen.
WHERE MyColumn != NULL
oder WHERE MyColumn = NULL
deterministisch? Oder wird mit anderen Worten garantiert immer 0 Zeilen zurückgegeben, unabhängig davon, ob sie MyColumn
in der Datenbank nullwertfähig sind oder nicht?
!=
nur Werte ausgewertet werden, WHERE MyColumn != 'somevalue'
die NULL-Datensätze nicht zurückgegeben werden.
NULL hat keinen Wert und kann daher nicht mit den Skalarwertoperatoren verglichen werden.
Mit anderen Worten, kein Wert kann jemals gleich (oder ungleich) NULL sein, da NULL keinen Wert hat.
Daher hat SQL spezielle IS NULL- und IS NOT NULL-Prädikate für den Umgang mit NULL.
'a' != null
KEINEN Wert ( true
/ 1
) zurückzugeben, und mich von Zeit zu Zeit erwischt! Ich hätte gedacht, "ein Wert im Vergleich zu keinem Wert" wäre immer "nicht gleich", aber vielleicht bin das nur ich?!?
SELECT * FROM MyTable WHERE coalesce(MyColumn, 'x') <> 'x'
normalerweise eine Konstante zuweisen, wenn es sich um einen NULL-Wert handelt, vorausgesetzt, Sie geben einen geeigneten Datentyp für den Sentinel-Wert x an (in diesem Fall eine Zeichenfolge / ein Zeichen). Dies ist die TSQL-Syntax, aber Oracle und andere Engines verfügen über ähnliche Funktionen.
Beachten Sie, dass dieses Verhalten das Standardverhalten (ANSI) ist.
Wenn du:
SET ANSI_NULLS OFF
http://msdn.microsoft.com/en-us/library/ms188048.aspx
Sie erhalten unterschiedliche Ergebnisse.
SET ANSI_NULLS OFF
wird anscheinend in Zukunft weggehen ...
create unique index UK_MyTable on MyTable (Column) where Column is not null
): msdn.microsoft.com/en-us/library/cc280372.aspx
SET ANSI_NULLS
AUS ist, folgen die Vergleichsoperatoren Equals (=) und Not Equal To (<>) nicht dem ISO-Standard. Eine verwendete SELECT-Anweisung WHERE column_name = NULL
gibt die Zeilen zurück, deren Spaltenname Nullwerte enthält. Eine verwendete SELECT-Anweisung WHERE column_name <> NULL
gibt die Zeilen zurück, deren Spalte nicht null Werte enthält. Außerdem gibt eine verwendete SELECT-Anweisung WHERE column_name <> XYZ_value
alle Zeilen zurück, die nicht XYZ_value und nicht NULL sind. IMHO, diese letzte Aussage scheint ein wenig seltsam, da sie Nullen aus den Ergebnissen ausschließt!
In SQL alles, was Sie mit NULL
Ergebnissen in UNBEKANNT auswerten / berechnen
Dies ist der Grund SELECT * FROM MyTable WHERE MyColumn != NULL
oder SELECT * FROM MyTable WHERE MyColumn <> NULL
gibt Ihnen 0 Ergebnisse.
Zur Überprüfung der NULL
Werte wird die Funktion isNull bereitgestellt.
Darüber hinaus können Sie den IS
Operator wie in der dritten Abfrage verwenden.
Hoffe das hilft.
Der einzige Test für NULL ist IS NULL oder IS NOT NULL. Das Testen auf Gleichheit ist unsinnig, da man per Definition nicht weiß, was der Wert ist.
Hier ist ein Wikipedia-Artikel zu lesen:
Wir gebrauchen
SELECT * FROM MyTable WHERE ISNULL(MyColumn, ' ') = ' ';
um alle Zeilen zurückzugeben, in denen MyColumn NULL ist, oder alle Zeilen, in denen MyColumn eine leere Zeichenfolge ist. Für viele "Endbenutzer" ist das Problem NULL vs. leere Zeichenfolge eine Unterscheidung ohne Notwendigkeit und Verwirrung.
Ich sehe nur nicht den funktionalen und nahtlosen Grund dafür, dass Nullen nicht mit anderen Werten oder anderen Nullen vergleichbar sind, weil wir sie klar vergleichen und sagen können, dass sie in unserem Kontext gleich sind oder nicht. Es ist lustig. Nur wegen einiger logischer Schlussfolgerungen und Beständigkeit müssen wir uns ständig damit beschäftigen. Es ist nicht funktional, macht es funktionaler und überlässt es Philosophen und Wissenschaftlern, zu schließen, ob es konsistent ist oder nicht, und enthält es "universelle Logik". :) Jemand könnte sagen, dass es an Indizes oder etwas anderem liegt. Ich bezweifle, dass diese Dinge nicht dazu gebracht werden konnten, Nullen wie Werte zu unterstützen. Es ist dasselbe wie zwei leere Gläser zu vergleichen, eines ist Weinglas und das andere ist Bierglas. Wir vergleichen nicht die Arten von Objekten, sondern die darin enthaltenen Werte, so wie Sie int und varchar mit null it vergleichen könnten. ' s noch einfacher, es ist nichts und was zwei Nichts gemeinsam haben, sie sind gleich, eindeutig vergleichbar von mir und allen anderen, die SQL schreiben, weil wir diese Logik ständig brechen, indem wir sie aufgrund einiger ANSI-Standards auf seltsame Weise vergleichen. Warum nicht Computerleistung verwenden, um dies für uns zu tun, und ich bezweifle, dass dies die Dinge verlangsamen würde, wenn alles, was damit zusammenhängt, in diesem Sinne konstruiert wird. "Es ist nicht null, es ist nichts", es ist nicht Apfel, es ist Apfel, komm schon ... Funktionell ist dein Freund und hier gibt es auch Logik. Am Ende kommt es nur auf die Funktionalität an, und die Verwendung von Nullen auf diese Weise bringt mehr oder weniger Funktionalität und Benutzerfreundlichkeit. Ist es nützlicher? weil wir diese Logik ständig brechen, indem wir sie aufgrund einiger ANSI-Standards auf seltsame Weise vergleichen. Warum nicht Computerleistung verwenden, um dies für uns zu tun, und ich bezweifle, dass dies die Dinge verlangsamen würde, wenn alles, was damit zusammenhängt, in diesem Sinne konstruiert wird. "Es ist nicht null, es ist nichts", es ist nicht Apfel, es ist Apfel, komm schon ... Funktionell ist dein Freund und hier gibt es auch Logik. Am Ende kommt es nur auf die Funktionalität an, und die Verwendung von Nullen auf diese Weise bringt mehr oder weniger Funktionalität und Benutzerfreundlichkeit. Ist es nützlicher? weil wir diese Logik ständig brechen, indem wir sie aufgrund einiger ANSI-Standards auf seltsame Weise vergleichen. Warum nicht Computerleistung verwenden, um dies für uns zu tun, und ich bezweifle, dass dies die Dinge verlangsamen würde, wenn alles, was damit zusammenhängt, in diesem Sinne konstruiert wird. "Es ist nicht null, es ist nichts", es ist nicht Apfel, es ist Apfel, komm schon ... Funktionell ist dein Freund und hier gibt es auch Logik. Am Ende kommt es nur auf die Funktionalität an, und die Verwendung von Nullen auf diese Weise bringt mehr oder weniger Funktionalität und Benutzerfreundlichkeit. Ist es nützlicher? s nicht Apfel, es ist Apfel, komm schon ... Funktionell ist dein Freund und hier gibt es auch Logik. Am Ende kommt es nur auf die Funktionalität an, und die Verwendung von Nullen auf diese Weise bringt mehr oder weniger Funktionalität und Benutzerfreundlichkeit. Ist es nützlicher? s nicht Apfel, es ist Apfel, komm schon ... Funktionell ist dein Freund und hier gibt es auch Logik. Am Ende kommt es nur auf die Funktionalität an, und die Verwendung von Nullen auf diese Weise bringt mehr oder weniger Funktionalität und Benutzerfreundlichkeit. Ist es nützlicher?
Betrachten Sie diesen Code:
SELECT CASE WHEN NOT (1 = null or (1 is null and null is null)) THEN 1 ELSE 0 end
Wie viele von Ihnen wissen, was dieser Code zurückgibt? Mit oder ohne NICHT gibt es 0 zurück. Für mich ist das nicht funktionsfähig und verwirrend. In c # ist alles so, wie es sein sollte, Vergleichsoperationen geben einen Wert zurück, logischerweise erzeugt auch dies einen Wert, denn wenn dies nicht der Fall ist, gibt es nichts zu vergleichen (außer nichts :)). Sie haben nur "gesagt": Alles im Vergleich zu null "gibt" 0 zurück und das schafft viele Problemumgehungen und Kopfschmerzen.
Dies ist der Code, der mich hierher gebracht hat:
where a != b OR (a is null and b IS not null) OR (a IS not null and b IS null)
Ich muss nur vergleichen, ob zwei Felder (in wo) unterschiedliche Werte haben, ich könnte Funktion verwenden, aber ...
NULL Mit den Vergleichsoperatoren kann kein Wert verglichen werden. NULL = NULL ist falsch. Null ist kein Wert. Der IS-Operator wurde speziell für NULL-Vergleiche entwickelt.
null = null
wo man es 1=0
in einer Ad-hoc-Abfrage verwenden könnte. Und wenn sie sich beschweren, ändere ich es auf null != null
:)
Alte Frage, aber die folgende könnte einige Details bieten.
null
repräsentiert keinen Wert oder einen unbekannten Wert. Es wird nicht angegeben, warum kein Wert vorhanden ist, was zu Mehrdeutigkeiten führen kann.
Angenommen, Sie führen eine Abfrage wie folgt aus:
SELECT *
FROM orders
WHERE delivered=ordered;
Das heißt, Sie suchen nach Zeilen, in denen Datum ordered
und delivered
Datum identisch sind.
Was ist zu erwarten, wenn eine oder beide Spalten null sind?
Da mindestens eines der Daten unbekannt ist, können Sie nicht erwarten, dass die beiden Daten identisch sind. Dies ist auch dann der Fall, wenn beide Daten unbekannt sind: Wie können sie gleich sein, wenn wir nicht einmal wissen, was sie sind?
Aus diesem Grund muss jeder Ausdruck, der null
als Wert behandelt wird, fehlschlagen. In diesem Fall stimmt es nicht überein. Dies ist auch der Fall, wenn Sie Folgendes versuchen:
SELECT *
FROM orders
WHERE delivered<>ordered;
Wie können wir wieder sagen, dass zwei Werte nicht gleich sind, wenn wir nicht wissen, was sie sind?
SQL hat einen speziellen Test für fehlende Werte:
IS NULL
Insbesondere werden keine Werte verglichen , sondern fehlende Werte gesucht.
Was den !=
Betreiber betrifft , so ist er meines Wissens in keinem der Standards enthalten, wird aber sehr weitestgehend unterstützt. Es wurde hinzugefügt, damit sich Programmierer aus einigen Sprachen wie zu Hause fühlen. Ehrlich gesagt, wenn ein Programmierer Schwierigkeiten hat, sich daran zu erinnern, welche Sprache er verwendet, hat er einen schlechten Start.
NULL
, meinen, dass wir einen Wert mit "einen NULL
Wert haben" vergleichen, nicht den Wert mit "dem unbestimmten Wert, den die Unterlage NULL
hat", aber dass wir es nicht wissen ", was wir natürlich nie erfahren werden. Das würde die Dinge wirklich erleichtern.
IS NULL
viel schwieriger ist als das Schreiben = NULL
. Ich denke, es wäre konsequenter, wenn WHERE columnA = columnB
es die gleiche Interpretation wie hätte WHERE columnA = NULL
, anstatt letzteres als Sonderfall zu behandeln. Denken Sie daran , dass NULL
ist nicht ein Wert. In Programmiersprachen , wo es ist legitim zu testen , variable == null
ist es, weil null
eine andere Bedeutung hat; es stellt nichts Unbekanntes dar, sondern ein absichtliches Zurücksetzen eines Wertes. Nicht so bei SQL.
IS NULL
UND =NULL
in Ihrem neuesten Beispiel kein Overhead besteht . Aber schauen Sie sich Hovers letzten an. Ich bin es leid, es immer wieder zu erleben und eine Menge unnötiger Dinge tun zu müssen? zusätzliche Überprüfung ...
Ich möchte diesen Code vorschlagen, den ich erstellt habe, um festzustellen, ob sich ein Wert ändert,
i
der neue Wert und d
der alte (obwohl die Reihenfolge keine Rolle spielt). Im Übrigen ist eine Änderung von Wert zu Null oder umgekehrt eine Änderung, von Null zu Null jedoch nicht (natürlich ist eine Änderung von Wert zu einem anderen Wert eine Änderung, von Wert zu demselben jedoch nicht).
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
Um diese Funktion zu verwenden, können Sie
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
Die Ergebnisse sind:
---- 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
Die Verwendung von sql_variant macht es für verschiedene Typen kompatibel
NULL ist nichts ... es ist unbekannt. NULL ist nichts gleich. Aus diesem Grund müssen Sie in Ihren SQL-Abfragen die magische Phrase IS NULL anstelle von = NULL verwenden
Sie können dies verweisen: http://weblogs.sqlteam.com/markc/archive/2009/06/08/60929.aspx
<>
dass es in der 92-Spezifikation ist, aber die meisten Anbieter unterstützen!=
und / oder es ist in einer späteren Spezifikation wie 99 oder 03 enthalten.