Impala SQL 左反连接
Impala SQL LEFT ANTI JOIN
目标是找到给定时间运行出现在左侧table但不出现在右侧table的empid。
我有以下两个 Impala 查询,我 运行 得到了不同的结果?
QUERY 1: select count(dbonetable.empid), COUNT(DISTINCT dbtwotable.empid) from
(select distinct dbonetable.empid
from dbonedbtable dbonetable
WHERE (dbonetable.expiration_dt >= '2009-01-01' OR dbonetable.expiration_dt IS NULL) AND dbonetable.effective_dt <= '2019-01-01' AND dbonetable.empid IS NOT NULL) dbonetable
LEFT join dbtwodbtable dbtwotable ON dbonetable.empid = dbtwotable.empid
--43324489 43270569
QUERY 2: select count(*) from (
select distinct dbonetable.empid from dbonedbtable dbonetable
LEFT ANTI join dbtwodbtable dbtwotable ON dbonetable.empid = dbtwotable.empid
AND (dbonetable.expiration_dt >= '2009-01-01' OR dbonetable.expiration_dt IS NULL) AND dbonetable.effective_dt <= '2019-01-01' AND dbonetable.empid IS NOT NULL) tab
--19088973
--For LEFT ANTI JOIN, this clause returns those values from the left-hand table that have no matching value in the right-hand table.
为了解释上下文,
查询 2:尝试使用我从此处学到的 LEFT ANTI JOIN 查找所有在 dbonetable 中但不在 dbtwotable 中的 empid:
https://www.cloudera.com/documentation/enterprise/5-9-x/topics/impala_joins.html
--对于 LEFT ANTI JOIN,此子句 returns 来自左侧 table 的那些值在右侧 table.
中没有匹配值
在查询 1 中:
基于 where 子句计算的 dbOnetable 和它的结果是 LEFT OUTER 与 dbtwotable 连接,在那个结果之上,我正在做一个计数(dbonetable.empid)和 COUNT( DISTINCT dbtwotable.empid) 结果是 --43324489 43270569,也就是 53,920。
我的问题是我的查询 1 结果应该是 43324489 -43270569 = 53,920 或者我的查询 2 结果应该是 19088973.
这里可能遗漏了什么,是我的查询 1 不正确吗?还是我的 LEFT ANTI JOIN 具有误导性?
提前谢谢大家。
这是不同的,因为您忘记在查询 1
中指定 "where dbtwotable.empid is null"
此外,您的查询 2 在逻辑上与查询 1 不同,因为在查询 1 中,您仅根据 empid1 和 empid2 的等价性进行联接,而在查询 2 中,您的联接具有更多条件,因此表中的公共条目要少得多与查询 1 相比,结果,最终计数要大得多。
如果您在查询 2 中创建与查询 1 中相同的连接条件,并将其他所有内容放入 where 子句中,您将获得与查询 1(更新)中相同的计数,即 53920。这就是您需要的计数
目标是找到给定时间运行出现在左侧table但不出现在右侧table的empid。 我有以下两个 Impala 查询,我 运行 得到了不同的结果?
QUERY 1: select count(dbonetable.empid), COUNT(DISTINCT dbtwotable.empid) from
(select distinct dbonetable.empid
from dbonedbtable dbonetable
WHERE (dbonetable.expiration_dt >= '2009-01-01' OR dbonetable.expiration_dt IS NULL) AND dbonetable.effective_dt <= '2019-01-01' AND dbonetable.empid IS NOT NULL) dbonetable
LEFT join dbtwodbtable dbtwotable ON dbonetable.empid = dbtwotable.empid
--43324489 43270569
QUERY 2: select count(*) from (
select distinct dbonetable.empid from dbonedbtable dbonetable
LEFT ANTI join dbtwodbtable dbtwotable ON dbonetable.empid = dbtwotable.empid
AND (dbonetable.expiration_dt >= '2009-01-01' OR dbonetable.expiration_dt IS NULL) AND dbonetable.effective_dt <= '2019-01-01' AND dbonetable.empid IS NOT NULL) tab
--19088973
--For LEFT ANTI JOIN, this clause returns those values from the left-hand table that have no matching value in the right-hand table.
为了解释上下文, 查询 2:尝试使用我从此处学到的 LEFT ANTI JOIN 查找所有在 dbonetable 中但不在 dbtwotable 中的 empid: https://www.cloudera.com/documentation/enterprise/5-9-x/topics/impala_joins.html --对于 LEFT ANTI JOIN,此子句 returns 来自左侧 table 的那些值在右侧 table.
中没有匹配值在查询 1 中: 基于 where 子句计算的 dbOnetable 和它的结果是 LEFT OUTER 与 dbtwotable 连接,在那个结果之上,我正在做一个计数(dbonetable.empid)和 COUNT( DISTINCT dbtwotable.empid) 结果是 --43324489 43270569,也就是 53,920。 我的问题是我的查询 1 结果应该是 43324489 -43270569 = 53,920 或者我的查询 2 结果应该是 19088973.
这里可能遗漏了什么,是我的查询 1 不正确吗?还是我的 LEFT ANTI JOIN 具有误导性? 提前谢谢大家。
这是不同的,因为您忘记在查询 1
中指定 "where dbtwotable.empid is null"此外,您的查询 2 在逻辑上与查询 1 不同,因为在查询 1 中,您仅根据 empid1 和 empid2 的等价性进行联接,而在查询 2 中,您的联接具有更多条件,因此表中的公共条目要少得多与查询 1 相比,结果,最终计数要大得多。
如果您在查询 2 中创建与查询 1 中相同的连接条件,并将其他所有内容放入 where 子句中,您将获得与查询 1(更新)中相同的计数,即 53920。这就是您需要的计数