J'ai une petite colonne sur une table dans une base de données SQL Server 2012.
J'essaie de récupérer toutes les lignes où cette colonne de bits est NULL
ou NOT TRUE.
Cette requête ne ramène pas ce qu'elle devrait: (retourne 0 lignes)
Select *
from table
where bit_column_value <> 1
Cette requête ramène les lignes correctes:
Select *
from table
where bit_column_value IS NULL
Maintenant, je serais heureux d'utiliser la deuxième requête, mais mon problème est que, dans une requête similaire pour une autre table, l'inverse de ce qui précède est vrai, où la première méthode fonctionne, mais pas la seconde!
Quelqu'un pourrait-il aider à expliquer quelle est la différence dans ce qui précède? J'ai spécifiquement mis à jour les colonnes de bits pertinentes pour qu'elles soient NULES et cela ne change pas les résultats. (Je pensais qu'il y avait peut-être une différence entre les valeurs "Empty" et Null
.
Merci d'avance pour toutes explications.
La raison <>
ne fonctionne pas, c'est que SQL traite NULL
comme inconnu - il ne sait pas ce que NULL
est censé signifier, donc il évalue les deux =
et <>
sur une valeur NULL
comme UNKNOWN
(qui est traitée comme fausse dans une clause where ou une condition de jointure). Pour plus d'informations, lisez ceci: Pourquoi NULL = NULL est-il évalué à faux dans le serveur SQL .
S'il y a un index dessus, l'utilisation de la fonction ISNULL signifie que l'index ne peut pas être utilisé, donc pour vous assurer que la requête peut utiliser l'index, utilisez simplement OR
:
SELECT *
FROM TableName
WHERE
bit_column_value IS NULL OR bit_column_value = 0
votre meilleur pari serait d'écrire la requête comme telle:
SELECT
*
FROM
table
WHERE
ISNULL(bit_column_value, 0) = 0
Cela devrait renvoyer tous les enregistrements NULL et FALSE.
Sans voir la structure et les données de votre table, je ne peux pas vraiment expliquer pourquoi vous obtenez des résultats différents à partir de vos 2 requêtes.
MSDN indique que le type BIT peut stocker les valeurs 0, 1 ou NULL. (Le fait qu'une valeur BIT soit NULL doit être stocké séparément de la valeur binaire elle-même, car les valeurs binaires peuvent être compressées de sorte que 8 valeurs BIT soient stockées dans un octet.)
N'oubliez pas qu'une condition dans une clause WHERE sélectionne une ligne lorsque la condition est VRAIE. Pour la plupart des prédicats binaires (conditions), si vous comparez NULL avec une certaine valeur, le résultat est NULL ou UNKNOWN (pas TRUE). Ainsi, par exemple, si la valeur d'une colonne est NULL, alors column = 0
prend la valeur NULL ou UNKNOWN, tout comme column <> 0
.
En regardant vos requêtes:
SELECT * FROM table WHERE bit_column_value <> 1
Où la valeur dans le bit_column_value
la colonne est 1, la condition est FALSE donc la ligne n'est pas retournée; où la valeur est 0, la condition est VRAIE donc la ligne est retournée; et lorsque la valeur est NULL, la condition est également NULL ou UNKNOWN, de sorte que la ligne n'est pas renvoyée.
SELECT * FROM table WHERE bit_column_value IS NULL
Selon le standard SQL, les prédicats IS [NOT] NULL) et les prédicats IS [NOT] {TRUE | FALSE | UNKNOWN} associés sont légèrement Le test IS NULL renvoie VRAI si la valeur testée est NULL; sinon, ils renvoient FAUX (et ne renvoient jamais INCONNU). Le IS [NON] Les tests {TRUE | FALSE | UNKNOWN} sont similaires; ils renvoient TRUE si la valeur est du type spécifié et FALSE sinon (pas UNKNOWN). Par exemple:
Column IS TRUE IS FALSE IS UNKNOWN IS NOT TRUE IS NOT FALSE IS NOT UNKNOWN
FALSE FALSE TRUE FALSE TRUE FALSE TRUE
TRUE TRUE FALSE FALSE FALSE TRUE TRUE
NULL FALSE FALSE TRUE TRUE TRUE FALSE
Ainsi, dans votre deuxième requête, seules les lignes où le bit_column_value
la valeur est NULL (qui est distincte de 0 et 1) sera sélectionné - pas le VRAI, ni le FAUX.
J'essaie de récupérer toutes les lignes où cette colonne de bits est NULL ou NOT TRUE.
Essayez d'écrire la requête directement à partir de vos spécifications:
SELECT * FROM table WHERE bit_column_value IS NULL OR bit_column_value IS NOT TRUE
SELECT * FROM table WHERE bit_column_value IS NULL OR bit_column_value = FALSE
SELECT * FROM table WHERE bit_column_value IS NULL OR bit_column_value <> TRUE
SELECT * FROM table WHERE bit_column_value IS NOT TRUE
Compte tenu de la table de vérité ci-dessus, la requête 4 donnerait le résultat souhaité - avec la mise en garde majeure que je ne suis pas certain que MS SQL Server prend en charge le IS [NOT] {TRUE | FALSE | UNKNOWN }. A en juger par MSDN sur Prédicats , les prédicats IS [NOT] {TRUE | FALSE | UNKNOWN} ne sont pas pris en charge (mais j'ai peut-être manqué la bonne partie de Si c'est correct, vous devez utiliser l'une des requêtes 2 ou 3.
(Il y a quelques complications supplémentaires avec ces prédicats lorsque la valeur n'est pas une simple colonne mais une valeur de ligne. Cependant, cela n'est pas pertinent pour votre question ou problème; doublement pas car MS SQL Server ne semble pas les prendre en charge.)
Je pense que c'est parce que toutes les données ont des valeurs NULL
dans cette colonne. Alors:
Select *
from table
where bit_column_value <> 1;
Ne vous donnera pas le résultat. Puisque NULL
est inconnu. Et ça:
Select *
from table
where bit_column_value IS NULL;
Vous donnera le résultat que vous recherchez.
Mais vous avez une idée fausse de représenter vrai et faux en utilisant le bit
type de données.
Vous représentez false comme NULL
, 0
est vide et vrai est toute autre valeur. Les types de données bit
fonctionnent comme @ IswantoSan expliqué dans sa réponse ; Ce doit être 0 ou 1 ou NULL
:
NULL
est vide.Par conséquent, pour obtenir:
true
les valeurs utilisent le where bit_column_value = 1
.false
les valeurs utilisent le where bit_column_value = 0
.NULL
ou vide where bit_column_value IS NULL
.NULL or not true:
où bit_column_value IS NULL ou bit_column_value = 0`.L'autre chose à noter est que NULL
et empty sont deux choses différentes, ce ne sont pas les mêmes. Dans le cas du type de données BIT
, vide est NULL
et non 0, car 0 est supposé être faux. Mais considérez un type de données de chaîne comme VARCHAR
par exemple, puis la chaîne vide ''
est totalement différent de la valeur NULL
.
Veuillez vérifier les données de votre table, si elles contiennent une valeur = 0?
type de données SQL Bit ne peut avoir que la valeur 0, 1 ou NULL
, si vous insérez une autre valeur, elle est considérée comme 1 (exception: si vous insérez 'False
'il deviendra 0,' True
'deviendra 1).
Par exemple :
insert into t1 values (1),(2),(1),(3),(-1),(0),(NULL),('false'),('true')
Le résultat :
1, 1, 1, 1, 1, 0, NULL, 0, 1