Один SQL-запрос с несколькими условиями - PullRequest
0 голосов
/ 14 февраля 2019

Я управляю базой данных Oracle и у меня есть две таблицы ниже.

#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       |
+------------+-------------+-------------+--------+---------------+

Хотите иметь подписку для каждого клиента:

  • последний успешный credit_request
  • сумма credit_amount всех неудачных credit_requests

Ответы [ 3 ]

0 голосов
/ 14 февраля 2019

Вот один из методов:

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;
0 голосов
/ 14 февраля 2019

Полагаю, что следующий запрос легко понять и реализовать.Кроме того, чтобы избежать все большего количества терминов в операторах CASE, вы можете просто использовать предложение WITH и использовать его в операторах CASE для уменьшения размера запроса.

     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 
0 голосов
/ 14 февраля 2019

Следующий запрос должен помочь.

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

Подзапрос присваивает последовательность каждой записи в группах счетов и типах кредитов, используя ROW_NUMBR().Внешний запрос выполняет условную агрегацию для вычисления различных вычислений, которые вы запрашивали.

Это Db Fiddle demo с вашими тестовыми данными:

ACC_ID | LAST_SUCCESSFULL_CREDIT_ID | LAST_SUCCESSFULL_CREDIT_DATE | LAST_SUCCESSFULL_CREDIT_AMOUNT | TOTAL_AMOUNT_OF_FAILED_CREDIT | RATIO_SUCCESS_REQUEST
-----: | -------------------------: | :--------------------------- | -----------------------------: | ----------------------------: | --------------------:
     1 |                       <em>null</em> | <em>null</em>                         |                           <em>null</em> |                          2200 |                     1
     2 |                       1214 | 02-DEC-18                    |                           1500 |                          3500 |                    .5
     3 |                       <em>null</em> | <em>null</em>                         |                           <em>null</em> |                             0 |                     0
     4 |                       1312 | 03-NOV-18                    |                           8750 |                             0 |                     0

Это может быть то, что вы ищете ... Поскольку вы не показали ожидаемых результатов, это может быть не на 100% точно, не стесняйтесь адаптировать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...