将单行转换为多行 Bigquery SQL
Posted
技术标签:
【中文标题】将单行转换为多行 Bigquery SQL【英文标题】:Convert single row into multiple rows Bigquery SQL 【发布时间】:2020-04-06 21:03:31 【问题描述】:在 bigQuery SQL 中将一行转换为多行。 行数取决于特定的列值(在本例中为 delta_unit/60 的值):
源表:
ID time delta_unit
101 2019-06-18 01:00:00 60
102 2019-06-18 01:01:00 60
103 2019-06-18 01:03:00 120
ID 102 确实记录了 01:01:00 的时间,而下一条记录是 01:03:00。 所以,我们缺少一条应该是 01:02:00 的记录,而 delta_unit = 60
预期表:
ID time delta_unit
101 2019-06-18 01:00:00 60
102 2019-06-18 01:01:00 60
104 2019-06-18 01:02:00 60
103 2019-06-18 01:03:00 60
根据 delta_unit 创建一个新行。需要创建的行数将取决于值 delta_unit/60(在这种情况下,120/60 = 2)
【问题讨论】:
你能提供更多的例子吗?只有一个逻辑不清楚。或者为什么? 在第一个数据集中,如果你查看时间列,你会发现 01:02:00 在序列中丢失了。这由 delta_unit 表示,即最后一次捕获记录是 2 分钟前(因此 delta_unit 在 01:03:00 分钟内为 120)有意义吗? 【参考方案1】:我找到了解决您问题的方法。我做了以下,先运行
SELECT max(delta/60) as max_a FROM `<projectid>.<dataset>.<table>`
计算最大步数。然后运行以下循环
DECLARE a INT64 DEFAULT 1;
WHILE a <= 2 DO --2=max_a (change accordingly)
INSERT INTO `<projectid>.<dataset>.<table>` (id,time,delta)
SELECT id+1,TIMESTAMP_ADD(time, INTERVAL a MINUTE),delta-60*a
FROM
(SELECT id,time,delta
FROM `<projectid>.<dataset>.<table>`
)
WHERE delta > 60*a;
SET a = a + 1;
END WHILE;
当然这不够高效,但它可以完成工作。 IDs 和 deltas 还没有以正确的值结束,它们不应该被需要。增量最终将全部为 60(可以删除该列),并且可以使用时间戳重新创建 ID 以对其进行排序。
您可以尝试在here 中使用条件表达式来避免循环并且只遍历表一次。
我试过了
INSERT INTO `wave30-webhelp-rmir.testing.spliting` (id,time,delta)
SELECT id+1, CASE
WHEN delta>80 THEN TIMESTAMP_ADD(time, INTERVAL 1 MINUTE)
WHEN delta>150 THEN TIMESTAMP_ADD(time, INTERVAL 2 MINUTE)
END
,60
FROM
(SELECT id,time,delta
FROM `wave30-webhelp-rmir.testing.spliting`
)
WHERE delta > 60;
但失败,因为只返回第一个条件,其中当为真。因此,我不确定是否可以一次完成所有操作。如果您有小桌子,我会坚持使用第一个可以正常工作的桌子。
【讨论】:
这很棒@aemon4,非常感谢!第一个解决方案似乎可以解决问题(我还没有尝试过第二个),我的表非常大,它按时间列分区(每天最多可以达到 150 GB)。我将在我拥有的列和记录最高的那一天尝试这个解决方案,看看这可能有多昂贵。以上是关于将单行转换为多行 Bigquery SQL的主要内容,如果未能解决你的问题,请参考以下文章