为什么LEFT JOIN删除行?

时间:2017-08-26 17:10:45

标签: sql

我已经使用sql很长一段时间了,但我现在在Databricks工作,我得到一个非常奇怪的结果。我有一个名为block_durations的表,带有一组id(称为block_ts),我还有另一个名为mergetable的表,我希望将其连接到该表。 Mergetable由acct_id和block_ts索引,因此每个block_ts都有许多不同的记录。我想保持block_durations中不匹配的行,如果在mergetable中有多个匹配,我希望在结果连接中有多个相应的条目,正如您对左连接所期望的那样。

但这不会发生。为了证明这一点,我在过滤单个acct_id后显示加入mergetable的结果,这样每个block_ts最多只有一个匹配。

select count(*) from mergetable where acct_id = '0xfbb1b73c4f0bda4f67dca266ce6ef42f520fbb98'
  

16579

select count(*) from block_durations
  

82817

select count(*) from
(
      SELECT 
      mt.*,
      bd.block_duration
      FROM
      block_durations bd
      left outer JOIN mergetable mt
        ON mt.block_ts = bd.block_ts
      where acct_id='0xfbb1b73c4f0bda4f67dca266ce6ef42f520fbb98'
) countTable
  

16579

正如您所看到的,即使block_durations中有> 80000条记录,其中大多数都会在左侧连接中丢失。为什么会这样?我认为左连接的重点是保留左表的不匹配行。这正是我期望从内部联接的行为 - 事实上当我切换到内部联接时没有任何改变。

有人可以帮我弄清楚发生了什么吗?

-Paul

1 个答案:

答案 0 :(得分:2)

保留连接左侧的所有行,但稍后您将删除与条件不匹配的行的WHERE ...条件。

WHERE条件合并到JOIN条件:

SELECT 
mt.*,
bd.block_duration
FROM
block_durations bd
left outer JOIN mergetable mt
  ON mt.block_ts = bd.block_ts AND acct_id='0xfbb1b73c4f0bda4f67dca266ce6ef42f520fbb98'

您还可以在结果{<1}}上运行mergetable之前对其进行过滤:

JOIN