J'utilise la requête ci-dessous pour obtenir les valeurs USD , mais lorsque Unit_price est nul, il doit renvoyer des valeurs nulles et je n'obtiens pas de valeurs nulles. Veuillez me dire où je vais mal. Merci!
DB: Oracle 11g
QUERY :
SELECT data_raw_id, f.ndc_cd, date_of_service, quantity_dispensed, p.unit_price, NVL((SELECT f.quantity_dispensed * pc.prc_amt FROM llpricing_lkup pc WHERE pc.ndc_cd = f.ndc_cd AND f.date_of_service BETWEEN pc.strt_dt AND pc.end_dt), f.quantity_dispensed * p.unit_price) usd FROM fact_data f JOIN product p ON f.ndc_Cd = p.ndc_Cd WHERE data_Raw_id in (44214229, 44214183, 41084896, 41244850, 41374409, 41501126, 41501107);
le résultat de la requête ci-dessus est ci-dessous.
S'il vous plaît, aidez-moi.
3 Réponses :
La fonction NVL dans oracle renvoie la première valeur non nulle. Votre fonction NVL -
NVL ((SELECT f.quantity_dispensed * pc.prc_amt FROM llpricing_lkup pc WHERE pc.ndc_cd = f.ndc_cd AND f.date_of_service BETWEEN pc.strt_dt AND pc.end_dt) , f.quantity_dispensed * p.unit_price) usd
Utilise un calcul de la table llpricing_lkup et doit renvoyer des valeurs. Par conséquent, vous n'obtenez aucune valeur nulle. Vous devez supprimer la sous-requête si vous souhaitez obtenir la colonne null dans la colonne USD.
Merci ankit pour votre aide
La fonction NVL ()
accepte deux arguments. Si e1
est évalué à null, alors la fonction NVL ()
renvoie e2
. Si e1
est évalué comme non nul, la fonction NVL ()
renvoie e1
.
Syntaxe ::
NVL (f.quantity_dispensed * p.unit_price,(SELECT f.quantity_dispensed * pc.prc_amt FROM llpricing_lkup pc WHERE pc.ndc_cd = f.ndc_cd AND f.date_of_service BETWEEN pc.strt_dt AND pc.end_dt)) usd
Donc, dans votre requête, l'instruction Select à l'intérieur de la fonction nvl n'est pas nulle, c'est pourquoi elle a renvoyé des données de colonne USD . Veuillez utiliser la requête ci-dessous à la place de la fonction NVL ()
.
NVL(e1, e2)
Merci Ajeet pour votre aide.
La solution la plus simple serait de placer l'expression usd
dans une expression case
qui spécifie votre règle métier:
nvl2(p.unit_price, f.quantity_dispensed * nvl(pc.prc_amt,p.unit_price), null) as usd
En regardant que, cependant, il semble que vous pourriez simplifier les choses en fusionnant votre sous-requête scalaire dans la requête principale en tant que jointure externe:
select data_raw_id , f.ndc_cd , date_of_service , quantity_dispensed , p.unit_price , case when p.unit_price is not null then f.quantity_dispensed * nvl(pc.prc_amt,p.unit_price) end as usd from fact_data f join product p on p.ndc_cd = f.ndc_cd left join llpricing_lkup pc on pc.ndc_cd = f.ndc_cd and f.date_of_service between pc.strt_dt and pc.end_dt where data_raw_id in (44214229, 44214183, 41084896, 41244850, 41374409, 41501126, 41501107);
La 'valeur de retour y ou z défendant si x est nul ' la logique peut également être exprimée en utilisant
nvl2 (some_value, value_if_not_null, value_if_null)
donc dans votre requête je fais ça: p >
select data_raw_id , f.ndc_cd , date_of_service , quantity_dispensed , p.unit_price , case when p.unit_price is not null then nvl ( ( select f.quantity_dispensed * pc.prc_amt from llpricing_lkup pc where pc.ndc_cd = f.ndc_cd and f.date_of_service between pc.strt_dt and pc.end_dt ) , f.quantity_dispensed * p.unit_price ) end as usd from fact_data f join product p on p.ndc_cd = f.ndc_cd where data_raw_id in (44214229, 44214183, 41084896, 41244850, 41374409, 41501126, 41501107);
mais je trouve toujours nvl2
moins lisible que l'expression case
équivalente.
Quant à savoir où vous vous trompez, la sous-requête scalaire llpricing_lkup
récupère les valeurs indépendamment de product.unit_price
, tant qu'une certaine quantité a été distribuée et une ligne de recherche de prix est définie couvrant la date du service, vous obtiendrez alors une valeur.
Merci beaucoup William pour l'explication détaillée.