Я не знаю, с чего начать этот запрос.
У меня есть следующие простые строки:
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
Как я могу это достичь? Я действительно понятия не имею,. Я нашел некоторые подобные вопросы, но на самом деле не понял.
Благодарю.
Я смог это сделать, создав таблицу с номерами от 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 |
+-------+------------+------------+---------------+
То, как я нашел для этого, требует дополнительной таблицы для хранения предстоящего количества месяцев для каждого конечного значения месяца. Это предполагает, что он будет применяться для ряда платежей, например, если общее количество предстоящих месяцев относительно невелико, например, 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);
EDIT I
Я вижу, что @MartinPierce опубликовал ответ в этих строках. Все равно я оставлю это из-за использования функции ADDDATE()
.