2013-06-27 5 views
2

мне нужно, чтобы получить количество последовательных unpayments:Ранжирование в течение нескольких последовательных дат

with payments as 
(
select '1' as ID, '20130331' as DateR, 'Not_paid' as Status from dual 
union 
select '1' as ID, '20130430' as DateR, 'Paid' as Status from dual 
union 
select '1' as ID, '20130531' as DateR, 'Not_paid' as Status from dual 
union 
select '2' as ID, '20130331' as DateR, 'Not_paid' as Status from dual 
union 
select '2' as ID, '20130430' as DateR, 'Not_paid' as Status from dual 
union 
select '3' as ID, '20130331' as DateR, 'Paid' as Status from dual 
union 
select '3' as ID, '20130430' as DateR, 'Paid' as Status from dual 
union 
select '3' as ID, '20130531' as DateR, 'Paid' as Status from dual 
) 

select ID, dater, status, dense_rank() over (partition by ID, status order by dater asc) rnk from payments 

Как видно из этого я получить нужное количество unpayments из ид 2: его первый unpayment был в марте, а второй в апреле. Идентификатор 3 тоже в порядке, потому что позже я его исключаю, но для id 1 он говорит, что вторая выплата была в мае, а я хочу сделать ее первой, потому что он не выплатил в марте, но снова заплатил в апреле, поэтому он должен начать оценивать оттуда. Как только он заплатил свой последний платеж, процесс начинается снова.

Идея состоит в том, чтобы сохранить ее просто без сложных запросов. Мне просто нужно сделать то же самое, что и с плотным рангом, но только в том случае, если даты совпадают

Надеюсь, что пример достаточно ясен.

Edit: Это то, что я получаю от текущего запроса:

ID DATER  STATUS RNK 
1 20130331 Not_paid 1 
1 20130531 Not_paid 2 
1 20130430 Paid  1 
2 20130331 Not_paid 1 
2 20130430 Not_paid 2 
3 20130331 Paid  1 
3 20130430 Paid  2 
3 20130531 Paid  3 

И то, что я хотел бы получить это:

ID DATER  STATUS RNK 
1 20130331 Not_paid 1 
1 20130430 Paid  1 
1 20130531 Not_Paid 1 
2 20130331 Not_paid 1 
2 20130430 Not_paid 2 
3 20130331 Paid  1 
3 20130430 Paid  2 
3 20130531 Paid  3 

, что если я хочу, чтобы получить максимальную (rank), чтобы проверить, сколько непогашенных платежей у пользователя в настоящее время у меня есть, у этого ID есть 1 платеж, ID 2 два последовательных невыплаты, а у ID 3 есть 0 неплатежей. Это связано с тем, что на четвертой последовательной неоплачиваемости я должен рассмотреть пользователя как взбесившийся.

Edit: 29/06/2013

Кто-то дал мне прекрасное решение в другом форуме: https://forums.oracle.com/thread/2555552

+0

Можете ли вы показать свой ожидаемый результат? Вы можете использовать 'LAG' для проверки прежнего состояния, что помогает при определении последовательных значений. –

+1

Привет, Ed, я отредактировал сообщение, чтобы сделать его более ясным, что я ожидаю. Я попробовал LAG, но я должен запросить его по таблице с 8 миллионами строк, и для обработки требуется очень много времени, тогда как плотный ранг занимает несколько секунд, и очень легко работать с результатом. – vdBurg

ответ

0

Это не полный ответ на ваш вопрос, но это возможное решение, чтобы получить количество невыплаченных неплатежей за каждый идентификатор. Он присваивает значение 1 для состояния Not_paid и -1 для Оплачено. Поэтому мы можем группировать запрос по ID и суммировать столбец значений, чтобы получить количество невыплаченных платежей. Для отрицательных сумм мы присваиваем нулю, поскольку у них нет невыплаченных платежей.

with payments as 
(
select '1' as ID, '20130331' as DateR, 'Not_paid' as Status from dual 
union 
select '1' as ID, '20130430' as DateR, 'Paid' as Status from dual 
union 
select '1' as ID, '20130531' as DateR, 'Not_paid' as Status from dual 
union 
select '2' as ID, '20130331' as DateR, 'Not_paid' as Status from dual 
union 
select '2' as ID, '20130430' as DateR, 'Not_paid' as Status from dual 
union 
select '3' as ID, '20130331' as DateR, 'Paid' as Status from dual 
union 
select '3' as ID, '20130430' as DateR, 'Paid' as Status from dual 
union 
select '3' as ID, '20130531' as DateR, 'Paid' as Status from dual 
) 
SELECT id, 
     DECODE(SIGN(SUM(value)), -1, 0, SUM(value)) 
    FROM (SELECT id, 
       dater, 
       status, 
       DECODE(status, 'Paid', -1, 1) value 
      FROM payments 
     ) 
GROUP BY id 
ORDER BY id; 

Теперь этот запрос работает для набора данных в вашем примере, но может не работать для больших наборов данных. Также он не будет работать, если для статуса Not_paid не будет равного количества статусов Платных платежей. Например, в вашем примере для ID = 2, если учетная запись полностью оплачена в мае, в вашем столе должно быть указано 2 платных ввода, чтобы мое решение работало. Если было загружено только 1 платная запись, тогда мое решение по-прежнему будет выдавать невыплаченный платеж за этот идентификатор.

+0

Спасибо! Это могло быть частичным решением, однако я получил прекрасный ответ на форумах Oracle. Я отредактировал комментарий со ссылкой в ​​случае, если кто-то заинтересован – vdBurg

 Смежные вопросы

  • Нет связанных вопросов^_^