标准 SQL:使用 BETWEEN 通过两个条件进行 LEFT JOIN
Posted
技术标签:
【中文标题】标准 SQL:使用 BETWEEN 通过两个条件进行 LEFT JOIN【英文标题】:Standard SQL: LEFT JOIN by two conditions using BETWEEN 【发布时间】: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 * FROMTable_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".
【参考方案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 的情况下实现相同的目标?以上是关于标准 SQL:使用 BETWEEN 通过两个条件进行 LEFT JOIN的主要内容,如果未能解决你的问题,请参考以下文章
如何在同一列或不同列的一个sql语句中两次使用'BETWEEN'条件
了解在 SQL 查询的自联接中使用“Between”条件时的逻辑查询处理