Я не знаю, с чего начать этот запрос.

У меня есть следующие простые строки:

event, date,        value, months left
foo    01/06/2018   700    7
bar    01/08/2018   50     5

Я хочу следующий вывод:

event, date,        value, months left
foo    01/06/2018   100    7
foo    01/07/2018   100    7
foo    01/08/2018   100    7
foo    01/09/2018   100    7
foo    01/10/2018   100    7
foo    01/11/2018   100    7
foo    01/12/2018   100    7
bar    01/08/2018   10     5
bar    01/09/2018   10     5
bar    01/10/2018   10     5
bar    01/11/2018   10     5
bar    01/12/2018   10     5

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

Спасибо.

0
Simon Breton 14 Сен 2018 в 22:24

2 ответа

Лучший ответ

Я смог это сделать, создав таблицу с номерами месяцев от 1 до 12.

> select * from events;
+-------+------------+--------+
| event | event_date | value  |
+-------+------------+--------+
| foo   | 2018-06-01 | 700.00 |
| bar   | 2018-08-01 |  50.00 |
+-------+------------+--------+

> select * from months;
+--------------+
| month_number |
+--------------+
|            1 |
|            2 |
|            3 |
|            4 |
|            5 |
|            6 |
|            7 |
|            8 |
|            9 |
|           10 |
|           11 |
|           12 |
+--------------+

> select event, concat(2018, '-', LPAD(month_number, 2, '00'), '-01') as curr_date, value / (13 - month(event_date)) as value, (13 - month_number) as months_remain from events, months where month_number >= month(event_date) order by event, months_remain desc;
+-------+------------+------------+---------------+
| event | curr_date  | value      | months_remain |
+-------+------------+------------+---------------+
| bar   | 2018-08-01 |  10.000000 |             5 |
| bar   | 2018-09-01 |  10.000000 |             4 |
| bar   | 2018-10-01 |  10.000000 |             3 |
| bar   | 2018-11-01 |  10.000000 |             2 |
| bar   | 2018-12-01 |  10.000000 |             1 |
| foo   | 2018-06-01 | 100.000000 |             7 |
| foo   | 2018-07-01 | 100.000000 |             6 |
| foo   | 2018-08-01 | 100.000000 |             5 |
| foo   | 2018-09-01 | 100.000000 |             4 |
| foo   | 2018-10-01 | 100.000000 |             3 |
| foo   | 2018-11-01 | 100.000000 |             2 |
| foo   | 2018-12-01 | 100.000000 |             1 |
+-------+------------+------------+---------------+
2
Marlin Pierce 14 Сен 2018 в 19:58

Способ, который я нашел для этого, требует дополнительной таблицы для хранения предстоящего количества месяцев для конечного значения каждого месяца. Это предполагает, что он будет применяться для ряда платежей, например, когда общее количество предстоящих месяцев относительно невелико, например, 12 месяцев.

Эта настройка предназначена только для образцов данных:

create table months_pool(
  month integer,
  mleft integer
);

month - количество бабочек, оставшееся, как указано в таблице событий. mleft меняется с 0 на month - 1. Он будет использоваться для вычисления даты для каждой записи результирующей таблицы.

insert into months_pool 
values
(7,0),(7,1),(7,2),(7,3),(7,4),(7,5),(7,6),
(5,0),(5,1),(5,2),(5,3),(5,4);

Запрос на результат:

select 
e.event, ADDDATE(date, interval mp.mleft month) dte, 
e.value/e.mleft val, 
e.mleft ml
from event e inner join months_pool mp on (e.mleft = mp.month)
order by e.event , ADDDATE(date, interval (mp.mleft) month);

РЕДАКТИРОВАТЬ Я

Я вижу, что @MartinPierce опубликовал ответ в этих строках. Все равно оставлю это из-за использования функции ADDDATE().

1
Juan 14 Сен 2018 в 20:41