对连接内的 'and' 过滤器感到困惑

Confusion about 'and' filter inside a join

能否解释一下 HiveQL 中这两个查询之间的区别。基本上我想从 table a 中过滤掉大于 2017-05-01 的日期。第二个查询没有给出我预期的结果,但第一个查询给出了。我以为他们是等价的

select a.user_id
, b.user_id
, a.event_date
, b.event_date
, to_date(a.event_date)
from default.t1 as a
left join stage.t2 as b
on a.user_id = b.user_id
and a.event_date = b.event_date
where a.event_date >= '2017-05-01'

对比

select a.user_id
, b.user_id
, a.event_date
, b.event_date
, to_date(a.event_date)
from default.t1 as a
left join stage.t2 as b
on a.user_id = b.user_id
and a.event_date = b.event_date
and a.event_date >= '2017-05-01'`

我发现了类似的问题,@Sandeep Jindal 的回答是最好的

SQL join: where clause vs. on clause

一个。 WHERE 子句:加入后。加入后将过滤记录。

b。 ON 子句 - 在加入之前。记录(从右边 table)将在加入前被过滤。这可能最终在结果中为 null(因为 OUTER join)。

A left join 保留第一个 table 中的所有行,无论 on 子句的计算结果是否为真。当 on 子句的计算结果为真时,它在第二个 table 中也有所有匹配的行。否则,第二个 table 的列是 NULL.

因此,left join 基本上忽略了第一个 table 上的任何过滤条件。无论如何,它将保留第一个 table 的行。

其实情况稍微复杂一些。如果 on 条件的计算结果不为真,则第二个 table 的列都是 NULL。因此,在第二个查询中,当日期不匹配时,b 中的列应该是 NULL.

怎么办?

  • left join 中第一个 table 的条件应始终放在 where 子句中。
  • 第二个 table 的条件应始终放在 on 子句中。