Ожидаемые платежи по дням с учетом даты начала и окончания - PullRequest
0 голосов
/ 04 января 2019

Я пытаюсь создать представление SQL, которое дает мне ожидаемую сумму, которая будет получена в течение календарного дня для повторяющихся транзакций. У меня есть таблица, содержащая данные повторяющихся обязательств, со следующими столбцами:

id, 
start_date, 
end_date (null if still active), 
payment day (1,2,3,etc.), 
frequency (monthly, quarterly, semi-annually, annually), 
commitment amount

Пока мне не нужно беспокоиться о рабочих и календарных днях.

В простейшей форме конечный результат будет содержать каждый исторический календарный день, а также будущие даты на следующий год, и даст информацию о том, сколько было / ожидается получить в эти конкретные дни.

Я провел немало исследований, но, похоже, не могу найти ответ, который решает конкретную проблему. Любое направление о том, с чего начать, будет принята с благодарностью.

Ожидаемый результат будет выглядеть примерно так:

| Date    | Expected Amount |

|1/1/18   |  100  | 
|1/2/18   |  200  | 
|1/3/18   |  150  | 

Спасибо заранее!

Ссылка на таблицу данных в db-fiddle
Таблица ожидаемых выходных данных

Ответы [ 2 ]

0 голосов
/ 05 января 2019

Это как-то так, но я никогда не использовал Netezza

SELECT 
  cal.d, sum(r.amount) as expected_amount
FROM
  (
    SELECT MIN(a.start_date) + ROW_NUMBER() OVER(ORDER BY NULL) as d
    FROM recurring a, recurring b, recurring c
  )  cal 
  LEFT JOIN
  recurring r
  ON 
    (
     (r.frequency = 'monthly' AND r.payment_day = DATE_PART('DAY', cal.d)) OR 
     (r.frequency = 'annually' AND DATE_PART('MONTH', cal.d) = DATE_PART('MONTH', r.start_date) AND r.payment_day = DATE_PART('DAY', cal.d))
    ) AND 
    r.start_date >= cal.d AND 
    (r.end_date <= cal.d OR r.end_date IS NULL)
GROUP BY cal.d

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

Таблица данных платежей оставлена ​​включенной в этот возрастающий ряд дат:

  • (день даты из серии) = (день платежа) для месячных
  • (месяц-день даты из серии) = (месяц и день платежа даты начала_)

Наконец, весь лот сгруппирован и суммирован

У меня нет тестового экземпляра Netezza, поэтому, если вы столкнетесь с какими-то незначительными синтаксическими ошибками, сделайте, пожалуйста, попытку исправить их самостоятельно (чтобы вы могли быстрее найти решение). Если вы дошли до того, что не можете понять, что делает запрос, дайте мне знать

0 голосов
/ 05 января 2019

Отказ от ответственности: я не эксперт по Netezza, поэтому я решил написать вам стандартный SQL, который может потребовать некоторой настройки для запуска на Netezza.

with
digit as (select 0 as x union select 1 union select 2 union select 3 union select 4
    union select 5 union select 6 union select 7 union select 8 union select 9
),
number as ( -- produces numbers from 0 to 9999 (28 years)
  select d1.x + d2.x * 10 + d3.x * 100 + d4.x * 1000 as n
  from digit d1
  cross join digit d2
  cross join digit d3
  cross join digit d4
),
expected_payment as ( -- expands all expected payments
  select
    c.start_date + nb.n as day,
    c.committed_amount
  from recurring_commitement c
  cross join number nb
  where c.start_date + nb.n <= c.end_data
    and c.frequency ... -- add logic for monthly, quarterly, etc. here
)
select
  day,
  sum(committed_amout) as expected_amount
from expected_payment
group by day
order by day

Это решение действительно для обязательств, которые не превышают 28 лет, поскольку число CTE (Common Table Expression) составляет максимум 9999 дней. Расширьте с помощью пятой цифры, если вам нужны более длинные обязательства.

Примечание : я думаю, что способ, которым я добавляю дни к дням к дате, не верен в SQL Netezza. Выражение c.start_date + nb.n может потребоваться перефразировать.

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