Заполняйте строки будущими датами, даже если нет значения - PullRequest
0 голосов
/ 06 августа 2020

История:

Мой набор данных выглядит так:

+---------+------+-----------------+---------+
|  Date   | Cost | Revenue   Month | Revenue |
+---------+------+-----------------+---------+
| 2018-01 |   20 | 2018-02         |      20 |
| 2018-01 |   20 | 2018-03         |     100 |
| 2018-02 |    5 | 2018-03         |      15 |
| 2018-02 |    5 | 2018-04         |      25 |
+---------+------+-----------------+---------+

В основном столбец даты представляет начальные инвестиции, а месяц дохода предназначен для денег, полученных за счет инвестиционный месяц. Я хотел бы заполнить строки для месяца дохода для каждого последующего месяца до текущего месяца и заставить доход показать 0 (т.е. август 2020 г.)

Цель:

+---------+------+-----------------+---------+---------+
|  Date   | Cost | Returning Month | Revenue | Product |
+---------+------+-----------------+---------+---------+
| 2018-01 |   20 | 2018-02         |      20 | A       |
| 2018-01 |   20 | 2018-03         |     100 | A       |
| 2018-01 |   20 | 2018-04         |     0   | A       |
| 2018-01 |   20 | 2018-05         |       0 | A       |
| 2018-02 |    5 | 2018-03         |      15 | A       |
| 2018-02 |    5 | 2018-04         |      25 | A       |
| 2018-02 |   5  | 2018-03         |       0 | A       |
| 2018-02 |   5  | 2018-03         |       0 | A       |

Что я пробовал:

Я построил эту таблицу дат подсчета

DROP TABLE IF EXISTS ##dates
CREATE TABLE ##dates ([date] Date)
DECLARE @dIncr DATE = '01/01/2018'
DECLARE @dEnd DATE = cast(getdate() as date)
WHILE (@dIncr <= @dEnd)
BEGIN
  INSERT INTO ##dates ([date]) VALUES (@dIncr)
  SELECT @dIncr = DATEADD(month,1,@dIncr)
END

Но я застрял на этом.

1 Ответ

1 голос
/ 06 августа 2020

Если вы хотите добавить два месяца к данным, вы можете использовать union all:

select  Date, Cost, Returning_Month, Revenue, Product 
from t
union all
select  Date, Cost, dateadd(month, v.n, Returning_Month), 0 as Revenue, Product 
from (select date, cost, max(returning_month) as returning_month, revenue, product
      from t
      group by date, cost, revenue, product
     ) t cross apply
     (values (1), (2)) v(n);

EDIT:

Использовать рекурсивный CTE:

with cte as (
      select date, cost, max(returning_month) as returning_month, revenue, product, 0 as lev
      from t
      group by date, cost, revenue, product
      union all
      select date, cost, dateadd(month, 1, returning_month), revenue, product, lev + 1
      from cte
      where returning_month < getdate()
     )
select date, cost, returning_month, revenue, product
from cte
where lev > 0;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...