混淆'和'过滤内部

问题描述:

可以解释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'` 
+0

您正在使用'left join',所以在第一个查询中,您将得到结果,其中'b.event_date'可以为null,然后筛选最终结果....在第二个日期条件中在连接中,所以你确保首先得到正确的数据....这是我的理解,但是,有人可以得到更好的解释 – Hackerman

A left join保留第一个表中的所有行,而不管on子句是否计算结果为true。当on子句的计算结果为true时,它也具有第二个表中的所有匹配行。否则,第二个表中的列是NULL

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

事实上,情况稍微复杂一些。如果on条件未评估为真,则第二个表中的列全部为NULL。因此,在第二个查询中,当日期不匹配时,b中的列应为NULL

怎么办?

  • left join中的第一个表上的条件应始终在where子句中。
  • 第二张桌子上的条件应该始终在on条款中。
+0

感谢提示何时在'on'和'where'子句中使用过滤器。我一直有困难缠绕我的头(不能想象它在我的头上) – lollerskates

我发现类似的问题,由金达尔@Sandeep的回答是最好的

SQL join: where clause vs. on clause

一个。 WHERE子句:加入后。记录将在联接发生后被过滤。

b。 ON条款 - 加入前。记录(来自右表)将在加入前被过滤。这可能会以结果为空(因为外部连接)。