Taux de change croisé

Firmin1977 -  
 Firmin1977 -
Bonjour,

je cherche à obtenir un taux de change croisé entre 2 devises, càd EUR/USD, GBP/USD, CHF/GBP, ...

J'ai 3 bases au départ: Opération (o); Changes (ch) et Personne (p) avec les champs suivants:

o.datvop "date valeur opération",
o.devise "Code devise opération",
o.mtneto "montant net opération",
ch.datvcc "date valeur change",
ch.devise "Code devise",
ch.chatau "taux de change",
p.devban "code devise de la banque",
p.ibanbq "Nom du compte bancaire",

Le taux change qui est alimenté par date par défaut dans la base change, est celui de l'EUR vers autres devises (ex: GBP vs EUR = 0,92). Pour le taux de change EUR/EUR, celui ci est de 1, mais à une seule date, celle du 01/01/1900 donc valeur vide pour toutes les autres dates. taux de change vide également si la date d'opération est supérieure à la dernière date de change connue (=> utilisation du max(chi.datvcc))

voici le code que j'ai écrit pour le calcul du taux de change:

SELECT decode(p.devban,o.devise,1,
((select decode(chbdi.chatau,'',
(decode(o.devise,'EUR',1,(select chatau
from changes
where datvcc=(select max(chi.datvcc)
from changes chi)
and devise=o.devise))),
chbdi.chatau)
from changes chbdi where chbdi.devise=o.devise)
/(select decode(chbdo.chatau,'',
(decode(p.devban,'EUR',1,(select chatau
from changes
where datvcc=(select max(chi.datvcc)
from changes chi)
and devise=p.devban))),
chbdo.chatau)
from changes chbdo where chbdo.devise=p.devban)))
as TxChangeBANDEP
FROM OPERATION o,
changes ch,
PERSONNE p
WHERE o.datvop = ch.datvcc(+) "il y a plusieurs enregistrements sur une date d'opération pour une seule par devise dans la table change"
and o.devise=ch.devise(+) "idem"

mais il me met le message suivant:
ORA-01427: Sous-interrogation ramenant un enregistrement de plus d'une ligne

Merci d'avance pour vos bons conseils

Laurent

PS: remarque importante, je travaille avec QlikView
A voir également:

1 réponse

pebkac
 
Salut,

j'ai juste survolé ta requête...
mais si Oracle te renvoie cette erreur, c'est qu'à un moment tu cherches à comparer une valeur (ou un n-uplet) au résultat d'une sous-requête qui renvoie plusieurs valeurs (ou plusieurs n-uplets)
donc
1. tu remplaces le '=' de ton prédicat par 'IN'
ou
2. tu corriges ta sous-requête pour qu'elle ne renvoie qu'une seule ligne (donc une valeur ou un n-uplet)

Bon courage
0
Firmin1977
 
Bonsoir pebcak,

Merci pour ta réponse.

J'ai déjà commencé par réduire les SELECT et suis arrivé à ceci:

SELECT o.datvop,
decode(p.devban,o.DEVISE,1,
decode(ch.chatau,NULL,decode(o.DEVISE,'EUR',1,ch_op.chatau),ch.chatau)
/ decode(ch.chatau,NULL,decode(p.DEVBAN,'EUR',1,ch_pers.chatau),ch.chatau))
AS TxChangeBANDEP,

FROM OPERATION o,
changes ch,
PERSONNE p,
(SELECT chatau,devise,datvcc
FROM changes
WHERE datvcc=(SELECT max(chi.datvcc) FROM changes chi WHERE chi.devise = devise)) ch_op,
(SELECT chatau,devise,datvcc
FROM changes
WHERE datvcc=(SELECT max(chi.datvcc) FROM changes chi WHERE chi.devise = devise)) ch_pers

WHERE o.datvop=ch.datvcc(+)
AND o.devise=ch.devise(+)
AND o.devise=ch_op.devise (+)
AND o.devise=ch_pers.devise (+)

cependant, il me reste toujours un soucis: dans la 2e partie de la division, ce n'est pas ch.chatau que je dois prendre, mais le taux de change par rapport à la devise du compte banque(p.DEVBAN)

Donc, en simplifié: Devise de l'opération/devise du compte banque.

Merci d'avance pour votre aide

Laurent
0