SQL n'est égal à & null
Nous aimerions écrire cette requête:
select * from table
where col1 != 'blah' and col2 = 'something'
Nous voulons la requête afin d'inclure les lignes où col1 est nul (et col2 = "quelque chose"). Actuellement, la requête ne sera pas le faire pour les lignes où col1 est null. Est la requête ci-dessous le meilleur et le plus rapide?
select * from table
where (col1 != 'blah' or col1 is null) and col2 = 'something'
Alternativement, nous pourrions, si nécessaire mettre à jour tous les col1 des valeurs null pour les cordes à vide. Serait-ce une meilleure approche? Alors notre première requête serait de travailler.
Mise à jour: Re: à l'aide de NVL: j'ai lu sur un autre post que ce n'est pas considéré comme une option à partir d'un point de vue performances.
- NVL: tout dépend de la quantité de données que vous interrogez. Vous avez toujours la possibilité de faire un index sur une fonction si la performance devient un problème.
- Nous avons un peu de données (100 lignes).
- Mais vous êtes un rétrécissement vers le bas sur "col2", où un index peut être utilisé. Le nombre de lignes que vous avez pour une valeur donnée sur "col2"?
- La plupart des 100K lignes ont une valeur pour col2 et col1 (environ 20% de col1 lignes sont nuls). Nous présentons toutes ces informations pour les utilisateurs et ils ont la capacité de filtrer les resultset.
- Nous sommes à l'aide de nvl sur les requêtes de 10mil+ enregistrements et ne sont pas avoir des problèmes de performances. Comme Thilo dit ci-dessus, vous pouvez utiliser d'autres indices de couper vers le bas avant de la nvl obtient évalué.
- FWIW, une assez standard SQL expression de vos critères serait
WHERE NULLIF(col1, 'blah') IS NOT NULL ...
C'est probablement la même incidence sur les performances comme la NVL approche. Il vaut mieux serait deIS DISTINCT FROM
, mais, comme @BillKarwin notes, qui n'est pas pris en charge dans Oracle. - Il n'y aura pas de différence de performances significative entre les requêtes à l'aide de
NVL(col1,'X')!='blah'
ou(col1!='blah' OR col1 IS NULL)
.
Vous devez vous connecter pour publier un commentaire.
Dans Oracle, il n'y a pas de différence entre une chaîne vide et NULL.
C'est le mépris le plus complet pour la norme SQL, mais là, vous allez ...
En plus de cela, vous ne pouvez pas comparer par rapport à NULL (ou non NULL) avec la "normale" des opérateurs: "col1 = null" ne fonctionnera pas, "col1 = "" ne fonctionne pas, "col1 != null" ne fonctionnera pas, vous devez utiliser le "null".
Donc, non, vous ne pouvez pas faire ce travail de toute autre manière, puis "col 1 est nulle" ou une variation qui (comme l'utilisation de nvl).
Je pense que la solution que vous avez posté est l'une des meilleures options.
Quant à la performance, à mon avis c'est pas une grande différence dans ce cas, si la clause en ont déjà un != comparaison habituellement l'optimiseur de ne pas utiliser un index dans cette colonne, en raison de la sélectivité n'est pas assez, de sorte que le plus discriminant filtre sera de l'autre côté de la condition "et".
Si vous me demandez, je ne vais pas utiliser une chaîne vide comme une valeur nulle, mais peut-être c'est juste une question de préférence personnelle.
Bien que pas le plus lisible - Oracle a une LNNVL Fonction c'est essentiellement la fonction not (), mais à l'inverse le comportement pour les valeurs null. Ce qui signifie que la comparaison n'importe quoi avec la valeur null à l'intérieur de lnnvl renvoie true (je ne sais pas quelles sont les performances des implications que cela peut avoir).
À faire ce que vous voulez en une seule instruction:
Notez que cela ne fonctionne que pour la comparaison d'une nullable valeur par rapport à une valeur que vous pouvez être assuré est pas les valeurs null. Sinon, vous aurez besoin de faire comme Thilo suggère d'utiliser un opérateur similaire à
Cela dépend de vos données, mais la plupart des optimiseurs allons regarder col2 avant col1, depuis = est plus facile d'indice que !=.
Sinon, il ya différentes façons que vous pouvez accélérer cette requête vers le haut. Il est probablement préférable de le faire (col1 != 'blah' ou col1 est nul), mais certains de la base de données vous permettent d'indice de la fonction. De sorte que vous pouvez l'indice de fusionner les colonnes(col1, 0) et d'obtenir de bonnes performances.
Vraiment cela dépend de vous et votre table.
Dans oracle utiliser la fonction nvl
Si vous voulez accélérer ce genre de requête, et vous êtes sur de Oracle 10g, utiliser une fonction d'index de base afin de transformer ces valeurs Null dans les valeurs:
La base de données sera très probablement utiliser l'index dans ce scénario (bien sûr, sous réserve de la décision de la communauté de base, touchés par les nombres de lignes et de l'exactitude des statistiques). La requête DOIT utiliser l'expression exacte donnée dans l'index - dans ce cas, "
NVL(col1,'***NULL***')
"Bien sûr, de choisir une valeur pour
'***NULL***'
qui ne seront pas en conflit avec toutes les données dans col1!Ce que sur cette option. Je pense que ça peut fonctionner que si votre valeur n'est jamais null.
qui aurait pour résultat suivant de la table de vérité pour évaluation pour la clause where
*c'est le seul qui est "mal" mais c'est ok depuis notre valeur n'est jamais null
Mise à jour
Ok, j'ai juste essayé de mon idée et il a échoué. Je vais le laisser ici la réponse à économiser du temps des autres tentent la même chose. Voici mes résultats:
Mise à jour 2
Cette solution fonctionne si votre valeur n'est jamais nulle (correspond à la table de vérité ci-dessus)
tests ici:
or 'blah' is null
est, par définition, de faux, de sorte qu'il n'ajoute rien à la requête du tout. Je ne comprends pas d'où vous venez; ou pourquoi vous êtes encore un réexamen de cette question vraiment.or col1 is null
. il fixe. J'ai abordé le problème en essayant de simplifier la requête en retrait de lais null
vérifier, mais n'a pas réussi, alors j'ai laissé mes tests ici pour référence future au cas où quelqu'un d'autre obtient les mêmes idées.Pour Oracle
Pour SqlServer
Je pense que votre augmentation serait minime dans l'évolution des valeurs NULL à des " chaînes de caractères. Cependant, si 'blah' n'est pas null, alors il devrait inclure des valeurs NULL.
EDIT: je suppose que je suis surpris de voir pourquoi j'ai voté ici-bas. Si 'blah' si pas de valeur null ou une chaîne vide, alors il ne devrait jamais question que vous êtes déjà vérifier si COL1 n'est pas égal à 'bla', ce qui n'est PAS une valeur NULL ou une chaîne vide.