【问题标题】:Fill rows between start and end dates in existing table填充现有表中开始日期和结束日期之间的行
【发布时间】:2021-09-14 02:27:42
【问题描述】:

我有一张表格,数据如下

对于 ID 列中的每个 ID,Movement_Val 列中有多个日期的条目。但是,中间有许多日期没有列出,而且 Movement_Val 列没有值。

我需要在 startdate (min(day)) 和 enddate (max(day)) 之间的每个日期添加一行。如果给定日期的 Movement_Val 列中存在值,则按原样填充该值。如果不存在任何值,我需要为该日期和 ID 填充 Movement_val 0。

生成的表格将如下所示

我怎样才能达到这个结果?

【问题讨论】:

  • 您能否添加您希望看到的输出的方式。
  • 谢谢@akshindesnowflake!我已经编辑了原始帖子以包含预期的输出。谢谢!

标签: sql snowflake-cloud-data-platform


【解决方案1】:

您需要一个日历表,您可以从中选择 min(day) 和 max(day) 之间的所有日期。您将日期列表与不同 ID 列表交叉连接,为日期和 ID 的每个组合提供一行。然后你将你的数据表连接到交叉连接,如果它存在则输出 move_val,否则输出 0。这是一个例子:

with calendar as (
select dateadd(DAY, row_number() over(order by null) - 1, '2020-01-01'::date) as cal_date
from table(GENERATOR(ROWCOUNT => 365))
),
movement_values as (
select 44026 as ID, '2020-07-16'::DATE as DAY, 104.19 as movement_val union all
select 13066 as ID, '2020-07-16'::DATE as DAY, 173.87 as movement_val union all
select 10794 as ID, '2020-07-17'::DATE as DAY, 3.81 as movement_val
)
select C.cal_date, ID_values.ID, nvl(M.movement_val, 0) as movement_val
from calendar C
cross join (select distinct ID from movement_values) ID_values
left join movement_values M on M.DAY = C.cal_date and M.ID = ID_values.ID
;

【讨论】:

  • 非常感谢!我会试试这个。如果我需要从现有表本身中选择开始日期和结束日期(而不是像上面的示例中那样明确指定开始日期和行数)并在这里使用它,我需要做什么?此外,由于实际表本身包含大约 180000 行,因此可能无法如示例中所示对每一行进行选择。我应该如何处理?谢谢!
  • 不确定您所说的“因为实际表本身包含大约 180000 行,因此可能无法对每一行进行选择”。我假设您已经有一个已填充的表,并且您将替换表名而不是我在示例中用作 CTE 的 motion_values。
  • 你可以像这样重写你的日历 CTE:## select dateadd(DAY, row_number() over(order by null) - 1, '2020-01-01'::date) as cal_date from table(GENERATOR(ROWCOUNT => 365)) 限定 cal_date 介于 (select min(day) from motion_values) 和 (select max(day) from motion_values) ## 同样,您可以将实际表的名称替换为 movement_values。在生成器部分,您将确保涵盖时间范围内的所有日期。
  • Maja:再次感谢您——我采纳了您对日历 CTE 的新建议,并且能够使用它获得预期的结果!非常感谢!
猜你喜欢
  • 1970-01-01
  • 2020-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多