如何在 BigQuery 中创建循环语句并添加自同一循环中每条记录的开始记录以来的天数差异?

列维 H。

我想创建一个带有 select 语句的表,对于每个记录,其中“Type = Start”采用与 Start-record 具有相同“Domain”的所有记录,并且具有与 Start-record 相同的时间戳或最多两年后。

此外,如果在此期间还有另一个起始记录也具有相同的域。在这些情况下,可以多次添加相同的记录。

我还想添加一个字段“天”,其中包含自开始记录以来的天数。

我想要一个附加的 id“New_Id”,它与 Start/domain/two-years-range 中所有记录的原始 Start-record 具有相同的 id。

我有一张桌子:

ID 领域 类型 时间戳 coll1 coll2
400 域 3 开始 2021-05-20T09:26:49 内容 内容
5 域2 其他 2021-02-14T12:16:32 内容 内容
100 域 1 开始 2021-04-13T03:23:11 内容 内容
4 域2 其他 2021-02-14T12:16:32 内容 内容
5 域2 其他 2021-05-10T13:16:35 内容 内容
200 域2 开始 2021-04-19T07:10:08 内容 内容
7 域 3 其他 2021-06-17T10: 30: 40 内容 内容
8 域 3 其他 2021-05-14T12:47:42 内容 内容
1 域 1 其他 2021-05-17T09:26:45 内容 内容
3 域 1 其他 2021-04-13T03:23:11 内容 内容
3 域 1 其他 2021-06-13T16:56:51 内容 内容
2 域 1 其他 2021-05-20T09:26:49 内容 内容
3 域 1 其他 2021-05-01T13:17:31 内容 内容
9 域 3 其他 2021-06-13T16:56:51 内容 内容
7 域 3 其他 2021-06-17T10: 30: 40 内容 内容
7 域 3 其他 2021-05-10T13:16:35 内容 内容
5 域2 其他 2021-04-19T07:10:08 内容 内容
1 域 1 其他 2021-05-14T12:47:42 内容 内容
300 域 3 开始 2021-05-13T08:40:04 内容 内容
8 域 3 其他 2021-05-17T09:26:45 内容 内容
5 域2 其他 2021-05-01T13:17:31 内容 内容

我想以这样的新表结束:

新 ID ID 领域 类型 时间戳 coll1 coll2
100 100 域 1 开始 2021-04-13T03:23:11 0 内容 内容
100 3 域 1 其他 2021-05-01T13:17:31 18 内容 内容
100 1 域 1 其他 2021-05-14T12:47:42 31 内容 内容
100 1 域 1 其他 2021-05-17T09:26:45 34 内容 内容
100 2 域 1 其他 2021-05-20T09:26:49 37 内容 内容
100 3 域 1 其他 2021-06-13T16:56:51 61 内容 内容
200 200 域2 开始 2021-04-19T07:10:08 0 内容 内容
200 5 域2 其他 2021-04-19T07:10:08 0 内容 内容
200 5 域2 其他 2021-05-01T13:17:31 12 内容 内容
200 5 域2 其他 2021-05-10T13:16:35 21 内容 内容
300 300 域 3 开始 2021-05-13T08:40:04 0 内容 内容
300 8 域 3 其他 2021-05-14T12:47:42 1 内容 内容
300 8 域 3 其他 2021-05-17T09:26:45 4 内容 内容
300 9 域 3 其他 2021-06-13T16:56:51 31 内容 内容
300 7 域 3 其他 2021-06-17T10: 30: 40 35 内容 内容
300 7 域 3 其他 2021-06-17T10: 30: 40 35 内容 内容
400 400 域 3 开始 2021-05-20T09:26:49 0 内容 内容
400 9 域 3 其他 2021-06-13T16:56:51 24 内容 内容
400 7 域 3 其他 2021-06-17T10: 30: 40 28 内容 内容
400 7 域 3 其他 2021-06-17T10: 30: 40 28 内容 内容
米哈伊尔·贝里安特

尝试以下方法(注意使用最近在预览中引入的 - QUALIFY子句)

select first_row.id as new_id, 
  id, domain, type, timestamp, 
  timestamp_diff(timestamp, first_row.timestamp, day) as days, 
  coll1, coll2
from (
  select *, 
    first_value(t) over(partition by domain, grp order by timestamp) first_row
  from (
    select *, 
      countif(type = 'Start') over(partition by domain order by timestamp) grp
    from `project.dataset.table`
  ) t
  where grp > 0 
  qualify timestamp_diff(timestamp, first_row.timestamp, day) < 2 * 365
) 
-- order by domain, timestamp              

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

enter image description here

UPDATE: in my initial answer above I've missed this part of OP's requirements: Also if there is another Start-record in this period that also have the same Domain. In those cases the same record can be added multiple times. Below answer addresses all OP's requirements

with starts as (
  select * from `project.dataset.table` where type = 'Start'
), others as (
  select * from `project.dataset.table` where type != 'Start'
)
select s.id as new_id, o.id, o.domain, o.type, o.timestamp, 
  timestamp_diff(o.timestamp, s.timestamp, day) as days, 
  o.coll1, o.coll2
from others o 
join starts s 
on s.domain = o.domain 
and o.timestamp >= s.timestamp
and timestamp_diff(o.timestamp, s.timestamp, day) < 2 * 365
union all 
select id as new_id, id, domain, type, timestamp, 0 as days, coll1, coll2
from starts
-- order by domain, new_id, timestamp 

If applied to sample data in the question - output is

enter image description here

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章