我有一个包含以下条目的表,
| ID | 日期 | 频率 |
|---|---|---|
| 1 | '2012-04-30' | 5 |
| 1 | '2012-06-30' | 4 |
| 1 | '2012-07-31' | 25 |
| 2 | '2012-04-30' | 7 |
| 2 | '2012-05-31' | 4 |
| 2 | '2012-06-30' | 1 |
| 2 | '2012-07-31' | 6 |
我需要添加缺失的月份,添加的日期应该是该月的最后一个日期,频率值为 0。
预期输出是
| ID | 日期 | 频率 |
|---|---|---|
| 1 | '2012-04-30' | 5 |
| 1 | '2012-05-31' | 0 |
| 1 | '2012-06-30' | 4 |
| 1 | '2012-07-31' | 25 |
| 2 | '2012-04-30' | 7 |
| 2 | '2012-05-31' | 4 |
| 2 | '2012-06-30' | 1 |
| 2 | '2012-07-31' | 6 |
我需要添加缺失的月份,添加的日期应该是该月份的最后一个日期
我建议使用递归 CTE:
with cte as (
select id, date, frequency,
lead(date) over (partition by id order by date) as next_date
from t
union all
select id, eomonth(date, 1), 0, next_date
from cte
where eomonth(date, 1) < dateadd(day, -1, next_date)
)
select id, date, frequency
from cte
order by id, date;
Run Code Online (Sandbox Code Playgroud)
CTE 的锚点部分计算给定行的结束日期。然后,递归部分不断添加月份来填充缺失的行(如果没有,则不填充)。使用eomonth(date, 1)只是获取下个月最后一天的便捷方法。
这是一个 db<>fiddle。
如果表中包含所有日期,您还可以使用cross join来生成行,然后left join引入现有数据:
select i.id, d.date, coalesce(t.frequency, 0) as frequency
from (select distinct id from t) i cross join
(select distinct date from t) d left join
t
on i.id = t.id and d.date = t.date
order by i.id, d.date;
Run Code Online (Sandbox Code Playgroud)
如果数据量很大,可以比较性能。在这种情况下,递归 CTE 可能比其他方法更快。
| 归档时间: |
|
| 查看次数: |
711 次 |
| 最近记录: |