SQL substituant la valeur NULL à l'aide de NVL, ayant des problèmes de vérification de la valeur substituée dans la clause where correctement
Je suis en cours d'exécution d'une requête pour afficher les messages lorsque la date est avant (<=) la date et l'to_date est après (>) la date actuelle.
Si le to_date
est NULL
, puis-je lui donner une valeur à l'aide de la NVL
méthode et de faire le chèque n la clause where, et si elle n'est pas nulle, c'est à dire l'utilisateur a fourni la valeur pour elle -, alors il devrait utiliser cette valeur et de la vérification de la condition de la clause where.
select a.id,
title,
body,
NVL(a.to_date, '9999-12-31 23:59:59') as todate,
cr_date
from a,
b
where a.cust_id = 20 and
a.body_id = b.body_id and
a.from_date <= current and
a.to_date > current
Cependant quand je fais exécuter cette requête pour ma base de données, je ne reçois que les résultats lorsque l'utilisateur a entré un to_date. Je NE suis PAS d'obtenir des résultats lorsque to_date est nulle et il a la valeur '9999-12-31 23:59:59' - c'est à dire:
Il échoue à l'un.to_date > état actuel, dans la clause where et n'a donc pas le retour de ces entrées. La valeur lors de la to_date est NULLE est remplacée correctement avec '9999-12 ...", mais à la condition where '> " actuel échoue.
Je veux faire de la substitution à l'intérieur de la requête et non pas comme une déclaration séparée. Logiquement je pense que cela devrait fonctionner, mais pour une raison que je vais mal quelque part . Aussi vous ne savez pas si cela a un impact sur l'exécution de la requête, mais la valeur par défaut de to_date est définie sur NULL lors de la création de la table.
Pouvez vous s'il vous plaît m'aider avec ce problème. Grâce
- Je vais avoir un moment difficile, mais n'est-il pas aussi simple que de changer
a.to_date > current
àNVL(a.to_date, '9999-12-31 23:59:59') > current
? Aussi, vous devriez vraiment être à l'aide de jointures de la norme ANSI, et pasa.body_id = b.body_id
. - Pourrait également utiliser la norme ANSI-fonction
COALESCE()
au lieu deNVL()
. - FUSIONNER n'est pas disponible dans Informix; NVL est.
- Ah, merci. La question n'est pas à l'origine préciser, donc, je suppose que c'était l'Oracle de la NVL().
Vous devez vous connecter pour publier un commentaire.
Je ne suis pas 100% clair sur votre question, mais il semble que vous voulez remplacer votre date évalué dans le
WHERE
clause, même si vous n'avez pas inclus lesNVL()
. Avez-vous essayé ceci:NVL(a.to_date, '9999-12-31 23:59:59') > current
à(a.to_date > current OR a.to_date IS NULL)
DATETIME
valeur. Fixe ma réponseVous avez besoin de lire sur NULL comparaison de la valeur - http://www.w3schools.com/sql/sql_null_values.asp
NULLE et 'SOME_DATE' ne peut pas être comparé avec =, < ou <> les opérateurs. La comparaison avec ces opérateurs sera toujours faux.
Donc, votre condition de "un.to_date > courant" sera toujours faux, et toutes les lignes avec une valeur NULL to_date ne sera jamais retourné.
Si vous en avez besoin retourné vous avez besoin de changer votre requête:
Espère que cette aide.
EDIT:
En fonction de vos commentaires, je voulais préciser qu'il y a un ordre de priorité dans l'exécution SQL. Dans ce cas, la clause from est évalué en premier, puis le OÙ et enfin la clause SELECT. Tout ce que vous faites dans la clause SELECT seulement affecte la façon dont la sortie est "affiché". Il ne change pas le nombre de lignes évalué. Dans votre exemple, la clause where a déjà éliminé les valeurs NULLES, de sorte que le NVL() de remplacement dans la clause SELECT est en fait redondante, car il n'y aura jamais de valeurs NULL dans la sortie.
NVL(a.to_date, '9999-12-31 23:59:59') as todate,
dans la clause select afin to_date doit jamais être null. Il faudrait 9999-12-31 23:59:59 compte tenu de l'sélectionner une condition ou à une valeur spécifiée par l'utilisateur. De sorte que la comparaison serait dans la clause where est valable....Je pense? Ai-je raison de penser ainsi?NVL(a.to_date, '9999-12-31 23:59:59') as todate
dans leSELECT
clause ne modifie pas la valeur deto_date
. Vous devez toujours utiliserNVL()
dans leWHERE
clause de faire de la sélectionnéto_date
valeur équivalente à la évaluéesto_date
.Le problème de base est que l'option "afficher les étiquettes" ou "alias de colonne' ne sont pas disponibles pour une utilisation dans le corps de la requête (la clause where). Vous pourriez contourner ce problème en utilisant une sous-requête:
Cela évite de répéter la NVL expression.
Note que vous avez eu un conflit entre
todate
COMME etto_date
dans le OÙ les. Je recommande également l'identification de la table dans laquelle chaque colonne vient d'lorsqu'une requête utilise plus d'une table (comme l'intérieur de la requête, mais la requête externe qui ne fonctionne pas). J'ai l'habitude de l'utiliser d'une seule lettre des alias pour les tableaux; cette fois, les alias sont inutiles puisque les noms de table sont une seule lettre de noms.Le plan de requête de ce sera probablement la même que pour la seule requête de niveau. Vous pouvez le vérifier à l'aide de SET EXPLIQUER, bien sûr.