sql—即使没有值,也用将来的日期填充行

zbdgwd5y  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(265)

故事:
我的数据集如下所示:

+---------+------+-----------------+---------+
|  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年8月)
目标:

+---------+------+-----------------+---------+---------+
|  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

但我被这个困住了。

6psbrbz9

6psbrbz91#

如果你想增加两个月的数据,你可以使用 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);

编辑:
使用递归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;

相关问题