【问题标题】:BigQuery BETWEEN JOINBigQuery BETWEEN JOIN
【发布时间】:2017-09-29 12:38:59
【问题描述】:

我想加入 BigQuery 中的 2 个表。表 1 具有整数,表 2 具有不重叠的整数范围(开始、结束)。我想加入表 1 和 2 给我这样的东西:

-- table 1
value
1
4
9
10

-- table 2
start, end
0,5
6,9
10,15

-- joined
value,start,end
1,0,5
4,0,5
9,6,9
10,10,15

我认为这个查询会起作用:

SELECT * 
FROM 
[table1] a
INNER JOIN [table2] b 
ON a.value BETWEEN b.start AND b.end

但这给了我这个错误

ON 子句必须是 AND of = 每个字段名称的比较 表,所有字段名都以表名为前缀

我可以通过这个 CROSS JOIN 查询得到正确的结果:

SELECT * 
FROM 
[table1] a
CROSS JOIN [table2] b 
WHERE a.value BETWEEN b.start AND b.end

但是docs 说如果可能的话应该避免这种情况:

CROSS JOIN 操作不允许 ON 子句。 CROSS JOIN 可以返回一个 大量数据,并可能导致查询缓慢且效率低下 或在超出每个查询允许的最大资源的查询中。 此类查询将失败并出现错误。如果可能,首选查询 不使用 CROSS JOIN

那么,是否可以使用 between 进行 INNER JOIN,或者以其他方式改进 CROSS JOIN?

【问题讨论】:

    标签: sql join google-bigquery


    【解决方案1】:

    这是 BigQuery Legacy SQL 的限制。

    您应该改用 BigQuery 标准 SQL:

    #standardSQL
    SELECT * 
    FROM 
    `table1` a
    INNER JOIN `table2` b 
    ON a.value BETWEEN b.start AND b.end   
    

    在标准 SQL 中 - 您应该使用反引号而不是括号。

    还请记住,end 是保留关键字,因此要完成上述工作,您还需要将其括在反引号中。

    见下文(连同您问题中的虚拟数据):

    #standardSQL
    WITH table1 AS (
      SELECT value 
      FROM UNNEST([1, 4, 9, 10]) AS value
    ),
    table2 AS (
      SELECT chunk.start, chunk.`end` 
      FROM UNNEST([STRUCT<start INT64, `end` INT64>(0,5),(6,9),(10,15)]) AS chunk
    )
    SELECT * 
    FROM `table1` a
    INNER JOIN `table2` b 
    ON a.value BETWEEN b.start AND b.`end`
    -- ORDER BY value
    

    【讨论】:

    猜你喜欢
    • 2020-05-17
    • 1970-01-01
    • 1970-01-01
    • 2016-04-03
    • 1970-01-01
    • 1970-01-01
    • 2012-07-28
    • 1970-01-01
    • 2020-04-21
    相关资源
    最近更新 更多