如何根据上一行有条件地插入一行?

问题描述

我目前正在尝试弄清如何根据上一行有条件地插入一行。我已经习惯了使用窗口函数,并且我想必须这样做才能完成这项工作,但是我不知道要使用其他任何函数来完成这项工作。

我正在使用的数据集看起来像这样

Original Table

我希望它看起来像这样:

After Modification

因此,实际上,我希望添加两个行日期之间存在的间隔。如果一行的结束日期和下一行的开始日期之间有间隔,我希望能够在它们之间插入一行具有相同项目的行,并存储中间的日期和已售出的金额的 0

我正在尝试在Google BigQuery控制台中执行此操作。

解决方法

您可以使用union alllead()

select item,store,start,end,sold
from t
union all
select item,dateadd(end,interval 1 day),dateadd(next_start,interval -1 day)
from (select item,lead(start) over (partition item,store start) as next_start
      from t
     ) t
where next_start  dateadd(end,interval 1 day);
,

您可以使用窗口函数和insert ... select语法创建“缺失”行:

insert into mytable (item,sold)
select 
    item,dateadd(lead_start,interval -1 day),0
from (
    select 
        t.*,lead(start) over(partition by item,store order by start) lead_start
    from mytable t
) t
where lead_start > dateadd(end,interval 1 day)
,

以下是用于BigQuery标准SQL

#standardSQL
SELECT * FROM `project.dataset.table` UNION ALL
SELECT * FROM (
  SELECT item,DATE_ADD(`end`,INTERVAL 1 DAY) new_start,DATE_SUB(LEAD(start) OVER(PARTITION BY item,store ORDER BY start),INTERVAL 1 DAY) new_end,0
  FROM `project.dataset.table` 
)
WHERE new_start <= new_end

如果要应用于您的问题的样本数据-输出为

Row item    store   start       end         sold     
1   5       1       2020-01-01  2020-01-15  22   
2   5       1       2020-01-16  2020-01-31  0    
3   5       1       2020-02-01  2020-02-20  14      

如果要在表中插入那些“缺失”的行,则应仅使用第二个选择-即

INSERT INTO `project.dataset.table`
SELECT * FROM (
  SELECT item,0
  FROM `project.dataset.table` 
)
WHERE new_start <= new_end