1
votes

Requête SQL ne renvoyant pas de valeurs Null

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.

 entrez la description de l'image ici

S'il vous plaît, aidez-moi.


0 commentaires

3 Réponses :


0
votes

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.


1 commentaires

Merci ankit pour votre aide



0
votes

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)


1 commentaires

Merci Ajeet pour votre aide.



1
votes

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.


1 commentaires

Merci beaucoup William pour l'explication détaillée.