SQL Функция окна, чтобы найти просроченные дни - PullRequest
0 голосов
/ 20 апреля 2020

Я хочу рассчитать DPD (просроченные дни) из списка займов, отсортированного по дате. Каждый просроченный срок должен пересчитываться. См. Пример в приложении . Как рассчитать столбец «Просроченные дни»?

DPD picture attach

Ответы [ 3 ]

0 голосов
/ 20 апреля 2020

Вы хотите сосчитать последовательные дни «просрочки» и сбросить счетчик между ними. Это пробелы и проблема островов.

Если даты всегда увеличиваются на 1 день, как показано в ваших данных выборки, то метод состоит в том, чтобы взять разницу между датой и row_number(), чтобы определить группу для каждой записи. принадлежат.

Вы не указали, какую базу данных вы используете, поэтому вот метод, который использует SQL Server * dateadd() для вычисления даты; базы данных, которые не поддерживают эту функцию, имеют эквивалентную функцию.

select
    loan_number,
    daydate,
    status,
    case when status = 'PastDue' then 
        count(*) over(
            partition by loan_number, status, dateadd(day, -rn, daydate)
            order by daydate
        ) 
        else 0
    end daysPastDue
from (
    select
        t.*,
        row_number() over(partition by loan_number, status order by daydate) rn
    from mytable t
) t
order by loan_number, daydate

Демонстрация на БД Fiddle :

loan_number | daydate    | status   | daysPastDue
----------: | :--------- | :------- | ----------:
     111111 | 2020-01-01 | Live     |           0
     111111 | 2020-01-02 | Live     |           0
     111111 | 2020-01-03 | PastDue  |           1
     111111 | 2020-01-04 | PastDue  |           2
     111111 | 2020-01-05 | Restruct |           0
     111111 | 2020-01-06 | Restruct |           0
     111111 | 2020-01-07 | Restruct |           0
     111111 | 2020-01-08 | PastDue  |           1
     111111 | 2020-01-09 | PastDue  |           2
     111111 | 2020-01-10 | Closed   |           0
0 голосов
/ 20 апреля 2020

Это должно сделать это.

SELECT
t1.LoanNumber, t1.daydate, t1.Status, case 
when status = 'Past Due'
  then datediff(day, 
             (select max(daydate) from table1 t2 
                where t2.loanNumber =t1.loanNumber 
                and t2.daydate<t1.daydate and t2.status<> 'Past Due'
             ),
             daydate)
   else 0 end as [Days Past Due]
from table1 t1

Вы можете попробовать это на sqlfiddle

0 голосов
/ 20 апреля 2020

Я читаю это как SQL Сервер по какой-то причине. Далее используется SQL Соглашения о сервере для функций даты. Другие базы данных имеют аналогичные функции, но точный синтаксис отличается.

Ключ ida - совокупный условный максимум - не изменяется:

select t.*,
       (case when status = 'PastDue'
             then datediff(date,
                           max(case when status <> 'PastDue' then dayDate end) over (partition by loadnumer order by daydate)
             else 0
        end) as daysPastDue
from t;
...