J'utilise une base de données Oracle et j'ai deux tableaux ci-dessous.
#account +----------------------------------+ | acc_id | date | acc_type | +--------+------------+------------+ | 1 | 11-07-2018 | customer | | 2 | 01-11-2018 | customer | | 3 | 02-09-2018 | employee | | 4 | 01-09-2018 | customer | +--------+------------+------------+ #credit_request +-----------------------------------------------------------------+ | credit_id | date | credit_type | acc_id | credit_amount | +------------+-------------+---------- +--------+ | 1112 | 01-08-2018 | failed | 1 | 2200 | | 1214 | 02-12-2018 | success | 2 | 1500 | | 1312 | 03-11-2018 | success | 4 | 8750 | | 1468 | 01-12-2018 | failed | 2 | 3500 | +------------+-------------+-------------+--------+---------------+
Je veux avoir les éléments suivants pour chaque client:
3 Réponses :
La requête suivante devrait faire l'affaire.
ACC_ID | LAST_SUCCESSFULL_CREDIT_ID | LAST_SUCCESSFULL_CREDIT_DATE | LAST_SUCCESSFULL_CREDIT_AMOUNT | TOTAL_AMOUNT_OF_FAILED_CREDIT | RATIO_SUCCESS_REQUEST
-----: | -------------------------: | :--------------------------- | -----------------------------: | ----------------------------: | --------------------:
1 | null | null | null | 2200 | 1
2 | 1214 | 02-DEC-18 | 1500 | 3500 | .5
3 | null | null | null | 0 | 0
4 | 1312 | 03-NOV-18 | 8750 | 0 | 0
La sous-requête attribue une séquence à chaque enregistrement, au sein de groupes de comptes et de types de crédit, en utilisant ROW_NUMBR () . La requête externe effectue une agrégation conditionnelle pour calculer les différents calculs que vous avez demandés.
Ce Démo Db Fiddle avec vos retours de données de test:
SELECT
acc_id,
MAX(CASE WHEN credit_type = 'success' AND rn = 1 THEN credit_id END) as last_successfull_credit_id,
MAX(CASE WHEN credit_type = 'success' AND rn = 1 THEN cdate END) as last_successfull_credit_date,
MAX(CASE WHEN credit_type = 'success' AND rn = 1 THEN credit_amount END) as last_successfull_credit_amount,
SUM(CASE WHEN credit_type = 'failed' THEN credit_amount ELSE 0 END) total_amount_of_failed_credit,
SUM(CASE WHEN credit_type = 'failed' THEN 1 ELSE 0 END) / COUNT(*) ratio_success_request
FROM (
SELECT
a.acc_id,
a.cdate adate,
a.acc_type,
c.credit_id,
c.cdate,
c.credit_type,
c.credit_amount,
ROW_NUMBER() OVER(PARTITION BY c.acc_id, c.credit_type ORDER BY c.cdate DESC) rn
FROM
account a
LEFT JOIN credit_request c ON c.acc_id = a.acc_id
) x
GROUP BY acc_id
ORDER BY acc_id
C'est peut-être ce que vous recherchez ... Puisque vous n'a pas montré les résultats escomptés, cela peut ne pas être précis à 100%, n'hésitez pas à l'adapter.
Voici une méthode:
select a.acct_id, acr.num_fails,
acr.num_successes / nullif(acr.num_fails) as ratio, -- seems weird. Why not just the failure rate?
last_cr.credit_id, last_cr.date, last_cr.credit_amount
from account a left join
(select acc_id,
sum(case when credit_type = 'failed' then 1 else 0 end) as num_fails,
sum(case when credit_type = 'failed' then credit_amount else 0 end) as num_fails,
sum(case when credit_type = 'success' then 1 else 0 end) as num_successes
max(case when credit_type = 'success' then date else 0 end) as max_success_date
from credit_request
group by acct_id
) acr left join
credit_request last_cr
on last_cr.acct_id = acr.acct_id and last_cr.date = acr.date;
Je suppose que la requête ci-dessous est facile à comprendre et à implémenter. De plus, pour éviter de plus en plus de termes dans les instructions CASE , vous pouvez simplement utiliser la clause WITH et l'utiliser dans les instructions CASE pour réduire la taille de la requête.
SELECT a.acc_id,
c.credit_type,
(distinct c.credit_id),
CASE WHEN
c.credit_type='success'
THEN max(date)
END CASE,
CASE WHEN
c.credit_type='failure'
THEN sum(credit_amount)
END CASE,
(CASE WHEN
c.credit_type='success'
THEN count(*)
END CASE )/
( CASE WHEN
c.credit_type='failure'
THEN count(*)
END CASE)
from accounts a LEFT JOIN
credit_request c on
a.acc_id=c.acc_id
where a.acc_type= 'customer'
group by c.credit_type
Excellent exercice, qu'avez-vous essayé?
Vos tables sont jolies. Veuillez également inclure un exemple du résultat attendu.
Devoirs, et vous attendez de nous que nous le fassions pour vous?!?
@jarlh - Eh bien, si vous avez raison, ils n'ont eu qu'à attendre 12 minutes pour obtenir la réponse complète ...
@MarmiteBomber a ajouté ma requête.
C'est une excellente question pour terminer avec ce qu'on appelle un cours pour débutants