【问题标题】:Standard SQL: LEFT JOIN by two conditions using BETWEEN标准 SQL:使用 BETWEEN 通过两个条件进行 LEFT JOIN
【发布时间】:2018-09-07 06:51:05
【问题描述】:

我在 BigQuery 中有以下查询:

#Standard SQL

SELECT *
FROM `Table_1`     
LEFT JOIN `Table_2` ON (timestamp BETWEEN TimeStampStart AND TimeStampEnd)

但我收到以下错误:

Error: LEFT OUTER JOIN cannot be used without a condition that is an equality of fields from both sides of the join.

如果我使用 JOIN 而不是 LEFT JOIN,它可以工作,但我想保留 Table_1 中的所有行(还有那些与 Table_2 不匹配的行)

如何做到这一点?

【问题讨论】:

  • 表1和表2是什么关系? ,如果没有关系,我更喜欢使用 Union 子句而不是在这种情况下不相关的连接
  • 表 1 包含一列带有时间戳(和一些其他变量),而表 2 还包含一些其他变量加上两列带有时间戳(一个表示开始时间,另一个表示结束时间) .所以我想合并这两个表,这样当 Table_1 的时间戳位于开始时间和结束时间之间时,两个表的变量就会被连接/合并。
  • 好的,你能试试 SELECT * FROM Table_1 LEFT JOIN Table_2 ON(table1.timestamp >= table2.TimeStampStart AND table1.timestamp
  • 我试过了,但不幸的是我仍然遇到同样的错误。
  • 您从谷歌搜索带有和不带标签的错误消息的众多点击中学到了什么? How to Ask 此外,左连接返回内连接行联合所有由空值扩展的不匹配的左表行。因此,您可以合并单独的部分。如果不是很明显,那肯定是一个常见问题。 PS请通过帖子编辑澄清,而不是cmets。 PS Re 用不等式替换:BigQuery does support inequality joins now - make sure to uncheck the "use legacy SQL option".

标签: sql date google-bigquery left-join


【解决方案1】:

这绝对是愚蠢的...但是如果您添加一个条件,将 table1 中的列与 table2 中的列相匹配,则相同的查询将起作用:

WITH Table_1 AS (
  SELECT CAST('2018-08-15' AS DATE) AS Timestamp, 'Foo' AS Foo
  UNION ALL
  SELECT CAST('2018-09-15' AS DATE), 'Foo'
), Table_2 AS (
  SELECT CAST('2018-08-14' AS DATE) AS TimeStampStart, CAST('2018-08-16' AS DATE) AS TimeStampEnd, 'Foo' AS Bar
)
SELECT *
FROM Table_1
LEFT JOIN Table_2 ON Table_1.Foo = Table_2.Bar AND Table_1.Timestamp BETWEEN Table_2.TimeStampStart AND Table_2.TimeStampEnd

查看您是否有其他可以使用的匹配条件(例如在相等时链接 table1 和 table2 的另一列)。

【讨论】:

  • 我想通了!谢谢!
  • 太棒了,这个答案让我很开心!
【解决方案2】:

LEFT JOIN 总是等价于 UNION 的:

同一连接谓词的相同两个参数之间的 INNER JOIN,以及 第一个参数中未找到匹配行的行集(并使用从第二个参数保留的所有列正确扩展为空值)

后面的部分可以写成

SELECT T1.*, null as T2_C1, null as T2_C2, ... 从 T1 WHERE 不存在(从 T2 WHERE 中选择 *)

因此,如果您拼出 UNION,您应该能够到达那里。

【讨论】:

    【解决方案3】:

    有趣。这适用于标准 SQL:

    select *
    from (select 1 as x) a left join
         (select 2 as a, 3 as b) b
         on a.x between b.a and b.b
    

    我怀疑您使用的是旧版 SQL。这样切换到标准 SQL。 (并在between 后面去掉括号。)

    问题是:

    #(Standard SQL)#
    

    这没有任何作用。使用:

    #StandardSQL
    

    【讨论】:

    • 谢谢。我不完全理解 1,2 和 3 在您的查询中代表什么。我只在示例中添加了#(Standard SQL)# 以说明我使用的是 StandardSQL,如果不清楚,请见谅。
    • @MC09 。 . .该查询只是标准 SQL 中接受该语法的演示。您的问题是查询被解释为旧版 SQL。
    【解决方案4】:

    您好,根据文档,“(”具有特殊含义,因此请尝试不带括号。

    SELECT * FROM Table_1 LEFT JOIN Table_2 ON Table_1.timestamp >= Table_2.TimeStampStart AND Table_1.timestamp <= Table_2.TimeStampEnd

    Documentation here

    【讨论】:

    • 还是同样的错误信息。有没有其他方法可以在不使用 LEFT JOIN 的情况下实现相同的目标?
    猜你喜欢
    • 1970-01-01
    • 2021-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-15
    • 1970-01-01
    相关资源
    最近更新 更多