J'ai un problème assez complexe que j'ai essayé de résoudre ces derniers jours. Je suis en train de le résoudre avec la clause Oracle SQL Model et j'aurais probablement pu écrire une fonction mais je cherche une solution simple et agréable utilisant des fonctions analytiques ou quelque chose mais ne pouvant rien comprendre.Recherche de déductions totales basées sur la somme des lignes précédentes dans SQL
Pour une politique donnée (ddpsid), je veux résumer la colonne des déductions (ddddpc). [Désolé pour les noms de colonnes difficiles, ils ne m'appartiennent pas]. Cela semble simple, mais si la colonne ddbnep est «Y», je veux résumer toutes les déductions antérieures et prendre la déduction actuelle en pourcentage de ce qui a déjà été déduit. Donc, si la déduction actuelle est de 10% et que les déductions antérieures sont de 20% (c.-à-d. Qu'il reste 80%), alors je veux déduire 8% (10% ou 80%), pour un total de 28%.
Le code ci-dessous est ce que je suis actuellement en utilisant:
with my_sample_data as (
select 1 as ddpsid, ddddsq, ddddpc, ddbnep, ddadep
from (
select 1 as ddddsq, 10 as ddddpc, 'N' as ddbnep, 'Y' as ddadep from dual union all
select 2 as ddddsq, 10 as ddddpc, 'Y' as ddbnep, 'Y' as ddadep from dual union all
select 3 as ddddsq, 10 as ddddpc, 'N' as ddbnep, 'Y' as ddadep from dual union all
select 4 as ddddsq, 10 as ddddpc, 'Y' as ddbnep, 'Y' as ddadep from dual
)
)
-- select
-- ddpsid,
-- cumul as ddddpc
-- from (
select
ddpsid,
ddddsq,
ddadep,
ddbnep,
ddddpc,
rn,
num_rows,
100 * (1-cumul) as cumul
from my_sample_data a
where ddadep = 'Y'
model
return all rows
partition by (ddpsid)
dimension by (row_number() over(partition by ddpsid order by ddddsq) as rn)
measures (ddddsq, ddadep, ddddpc, ddbnep, 0 as cumul,
count(*) over(partition by ddpsid) as num_rows)
rules automatic order (
cumul[rn] = case
when nvl(ddbnep[cv(rn)],'N') = 'N'
then nvl(cumul[cv(rn)-1],1)- ddddpc[cv(rn)] /100
else nvl(cumul[cv(rn)-1],1)* (1- ddddpc[cv(rn)]/100) end
)
-- )
-- where rn = num_rows
Les données doivent être regroupées par ddpsid et traitées afin de ddddsq. La combinaison de ddpsid et ddddsq devrait être unique. Le pourcentage de déduction est dans la colonne ddddpc. Je veux seulement traiter les lignes où ddadep = 'Y'. Et enfin, si la colonne ddbnep = 'N' alors je veux juste ajouter ddddpc au total cumulé, sinon si ddbnep = 'Y' je veux prendre ddddpc en pourcentage de (100% - le total cumulé) et l'ajouter au total cumulé.
Le code commenté est nécessaire parce que je ne veux vraiment que la dernière valeur pour chaque ddpsid mais il montre le fonctionnement un peu mieux sans cela. Désolé pour la question longue mais il s'agit de la description la plus concise que je peux fournir.
Le code ci-dessus montre quatre déductions, deux normales et deux nettes de prior.
- La première à 10% est normale et donne un total cumulé de 10%.
- La seconde à 10% est nette de précédente. Les déductions antérieures totalisaient 10%, de sorte qu'il reste un montant de 90%. Donc, cette déduction devrait être de 9%, ce qui donne un total cumulé de 19%
- Le troisième à 10% est normal et donne un total cumulé de 29%.
- La finale à 10% est également nette de précédente. Les prélèvements antérieurs ont totalisé 29%, de sorte qu'il reste un montant de 71%. Donc, cette déduction devrait être de 7,1%, soit un total de 36,1%
Après avoir essayé pendant deux ou trois jours d'essayer de trouver une solution SQL, je suis un peu déçu que je ne puisse pas J'espère que je n'ai rien manqué.
Donc, est-il possible de réécrire ceci sans utiliser la clause modèle et sans écrire de fonction?
Je suis sur 10.2 donc l'affacturage sous-requête récursif n'est pas possible. N'avait jamais utilisé la clause modèle avant parce que je n'avais jamais trouvé le besoin. Ce n'est pas que je ne voulais pas l'utiliser, j'étais juste avec le sentiment qu'il devait y avoir une autre solution que je ne pouvais pas voir ... mais on dirait qu'il n'y en a pas. –