Google bigquery BigQuery中的自连接问题
我试图对当前行周围特定日期范围的值求和。由于Bigquery不支持windows函数中的日期范围,因此我使用自连接,如下所示:Google bigquery BigQuery中的自连接问题,google-bigquery,Google Bigquery,我试图对当前行周围特定日期范围的值求和。由于Bigquery不支持windows函数中的日期范围,因此我使用自连接,如下所示: with test_data as ( select 1 val1, 7 val2, 'ord001' id, timestamp('2019-01-01 04:00:00') dt_order union all select 2 val1, 14 val2, 'ord002' id, timestamp('2019-01-02 05:00:00')
with test_data as (
select 1 val1, 7 val2, 'ord001' id, timestamp('2019-01-01 04:00:00') dt_order
union all
select 2 val1, 14 val2, 'ord002' id, timestamp('2019-01-02 05:00:00') dt_order
union all
select 3 val1, 21 val2, 'ord003' id, timestamp('2019-01-03 06:00:00') dt_order
)
,revenue_coeff as (
select
td.id,
td.val1 *
(select sum(td1.val2) / sum(td1.val1)
from test_data td1
where td1.dt_order >= timestamp_sub(td.dt_order, interval 24 hour) and
td1.dt_order < timestamp_add(td.dt_order, interval 6 minute)
)
from test_data td
)
select * from revenue_coeff
这个玩具查询工作得很好。但是,当我试图使用一个真正的BigQuery表时,我得到了一条“如果没有一个条件,即连接两边的字段相等,则不能使用左外部连接”消息。
如何在BQ中实现这样的查询?提前谢谢 下面是BigQuery标准SQL 我会在你文章的末尾首先回答你的问题,但随后会在你文章的顶部发表你的声明。所以 我得到了一条“如果没有连接两边字段相等的条件,就不能使用左外连接”消息。如何在BQ中实现这样的查询 正如您所看到的-诀窍在于使用UNIX_SECONDS函数将时间戳数据类型转换为int
显然-我建议您使用第二个选项您也可以执行左外连接,如:
select a.val1, a.id,
sum(if(b.dt_order >= timestamp_sub(a.dt_order, interval 24 hour) and b.dt_order <= timestamp_add(a.dt_order, interval 6 minute), b.val2, 0.0))
/
sum(if(b.dt_order >= timestamp_sub(a.dt_order, interval 24 hour) and b.dt_order <= timestamp_add(a.dt_order, interval 6 minute), b.val2, 0.0))
from test_data a
left join test_data b on 1=1
group by 1,2
但是,您必须管理上游的零除法错误,或者在其中添加case语句。这样对其他人来说就很清楚了-左JOIN with ON TRUE只是说CROSS JOINYes的很长一段路。尽管有些人觉得它没有交叉连接那么冗长/混乱。同意。这可能是个人偏好的问题,而个人偏好又来自经验。所以,对我来说,这是完全相反的-在这种情况下使用交叉连接-看起来不那么冗长,也不那么混乱,因为它明确地表达了应该做什么,即交叉连接与使用左连接欺骗系统。。。真的然而,true上的左连接和交叉连接之间的区别在于,左连接实际上保留了左表-交叉连接没有。您的速率很低。重要提示-您可以使用投递答案左侧投票下方的勾号标记接受答案。看看为什么它很重要!同样重要的是对答案进行投票。投票选出有帮助的答案。。。当有人回答你的问题时,你可以检查一下该做什么。遵循这些简单的规则,你可以提高自己的声望得分,同时让我们有动力去回答你的问题:O请考虑!谢谢你详细的回答。对于这个问题,这确实是一个优雅的解决方案。仍然不能同意您对BQ中日期范围的支持,代码需要一些注释,这不是自解释的。
#standardSQL
WITH `project.dataset.test_data` AS (
SELECT 1 val1, 7 val2, 'ord001' id, TIMESTAMP('2019-01-01 04:00:00') dt_order UNION ALL
SELECT 1 val1, 14 val2, 'ord002' id, TIMESTAMP('2019-01-02 05:00:00') dt_order UNION ALL
SELECT 1 val1, 21 val2, 'ord003' id, TIMESTAMP('2019-01-03 06:00:00') dt_order
), revenue_coeff AS (
SELECT id, val1 * SUM(val2) OVER(win) / SUM(val1) OVER(win)
FROM `project.dataset.test_data` td1
WINDOW win AS (ORDER BY UNIX_SECONDS(dt_order) RANGE BETWEEN 86400 PRECEDING AND 359 FOLLOWING )
)
SELECT * FROM revenue_coeff
select a.val1, a.id,
sum(if(b.dt_order >= timestamp_sub(a.dt_order, interval 24 hour) and b.dt_order <= timestamp_add(a.dt_order, interval 6 minute), b.val2, 0.0))
/
sum(if(b.dt_order >= timestamp_sub(a.dt_order, interval 24 hour) and b.dt_order <= timestamp_add(a.dt_order, interval 6 minute), b.val2, 0.0))
from test_data a
left join test_data b on 1=1
group by 1,2