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