Ich habe ein unerwartetes Postgres-Problem in meiner Rails3-App festgestellt.
Ich dachte, ich würde dies mit stackoverflow ausführen und sehen, was die Gehirne des Internets zu sagen haben:)
Ist das Ergebnis erwartetes Verhalten (und warum ?!) oder ist das ein Fehler?
Da ich eine Tabelle habe, Bestellungen, in meiner Postgres 9.1.4 Datenbank:
%Vor%Wenn ich die Abfrage ausführen:
%Vor%Ich habe das Ergebnis erwartet [1, 3]. Es gibt eindeutig 2 Zeilen, in denen (! = 'Erfolg') erfüllt ist.
Warum ist das Nil!="Erfolg" ist hier nicht wahr? Ist! = NULL Werte ignorieren? sollte es?
HINWEIS: Ich habe das gewünschte Ergebnis mit der folgenden Abfrage erzeugt:
%Vor%Irgendwelche Kommentare würden geschätzt.
Es gibt einen Vergleichsoperator IS DISTINCT FROM in PostgreSQL:
Gewöhnliche Vergleichsoperatoren ergeben null (was "unbekannt" bedeutet), nicht wahr oder falsch, wenn eine der Eingaben null ist. Zum Beispiel liefert
%Vor%7 = NULL
null, ebenso wie7 <> NULL
. Wenn dieses Verhalten nicht geeignet ist, verwenden Sie dieIS [ NOT ] DISTINCT FROM
-Konstrukte:Für Eingaben ungleich null entspricht
IS DISTINCT FROM
dem Operator<>
. Wenn beide Eingaben jedoch null sind, wird false zurückgegeben, und wenn nur eine Eingabe null ist, wird true zurückgegeben. Auf ähnliche Weise istIS NOT DISTINCT FROM
identisch mit=
für Eingaben ungleich null, aber es gibt true zurück, wenn beide Eingaben null sind, und false, wenn nur eine Eingabe null ist. Daher verhalten sich diese Konstrukte effektiv so, als ob null ein normaler Datenwert wäre und nicht "unbekannt".
Beispiel für Ihre Beispieldaten:
%Vor%So könnte man das sagen:
%Vor% Beachten Sie, dass ich auch in pluck
anstatt in map(&:id)
gewechselt habe, das diese SQL an die Datenbank sendet:
statt select orders.* ...
mit dem clientseitigen Filter, um id
s zu extrahieren.
Dies ist Teil des SQL-Standards, bei dem ein Vergleich zwischen zwei Werten, die mindestens einen NULL-Wert enthalten, weder wahr noch falsch, aber unbekannt zurückgibt.
Von Ссылка
- Ein boolescher Vergleich zwischen zwei Werten, die einen NULL-Wert enthalten, gibt weder wahr noch falsch zurück, ist aber in der dreiwertigen Logik von SQL unbekannt. [3] Zum Beispiel ist weder NULL gleich NULL noch NULL nicht gleich NULL ist wahr. Das Testen, ob ein Wert NULL ist, erfordert einen Ausdruck wie IS NULL oder IS NOT NULL.
- Eine SQL-Abfrage wählt nur Werte aus, deren WHERE-Ausdruck true ergibt, und Gruppen, deren HAVING-Klausel true ergibt.
Eine Lösung ist die Verwendung von COALESCE:
%Vor% Wenn orders.state
NULL ist, wird es durch 'NIL' ersetzt, was dann wahr oder falsch aus dem Vergleich zurückgibt.
Sie können natürlich eine zusätzliche Bedingung verwenden:
%Vor%Tags und Links sql ruby-on-rails postgresql null