带有 OR 子句的 SQL 连接

Lun*_*Box 0 t-sql sql-server

假设我们有以下查询

select
     *
from
     table_1 as a
left join
     table_2 as b
     on
          a.[id_1] = b.[emp_id] OR
          a.[id_1] = b.[worker_id]
Run Code Online (Sandbox Code Playgroud)

该查询与以下查询有何不同:

    select
         *
    from
         table_1 as a
    left join
         table_2 as b
         on
              a.[id_1] = b.[emp_id] 

union

    select
         *
    from
         table_1 as a
    left join
         table_2 as b
         on
              a.[id_1] = b.[worker_id]
Run Code Online (Sandbox Code Playgroud)

就结果而言,这两个查询不是同义词吗?与联合的查询执行得更快,但我得到了不同的记录数,这就是我问的原因。

编辑 #1

没有索引,我不允许添加任何索引。

顶部查询需要 20 分钟才能运行。底部查询需要 2 分钟才能运行。

这就是为什么我试图以复制顶部查询的方式操作底部查询。

在顶级查询中返回 39,758 条记录。第二次返回大约 78,000 条记录。

使用 anOR而不是 anIN因为这是有人设计存储过程的方式。我只是将它拆开来尝试调整存储过程中的其他内容。

编辑#2:

我正在创建#temp 表并在这些表上添加索引作为解决方案。在添加索引之前,我需要确保我复制了相同数量的记录。

**编辑#3:**

如果你想重现我在做什么,这里有一个例子:

drop table #temp;
go

drop table #temp_2;
go
-----------------------------------

select
    1 as [id],
    cast('good' as varchar(255)) as [status]
into
    #temp;

go

insert into #temp(id,[status]) values
(2, 'bad'), (3, 'great'), (4, 'average');

go
------------------------------------------

select
    1 as [id],
    cast('good' as varchar(255)) as [status]
into
    #temp_2;
go

insert into #temp_2(id, [status]) values
(2, 'average'), (5, 'average'), (6, 'average');

go
-------------------------------------------------
select
    a.*,
    b.*
from
    #temp as a
left join
    #temp_2 as b
    on
        a.[id] = b.[id];

go

select
    a.*,
    b.*
from
    #temp as a
left join
    #temp_2 as b
    on
        a.[status] = b.[status];

go

select
    a.*,
    b.*
from
    #temp as a
left join
    #temp_2 as b
    on
        a.[id] = b.[id] OR
        a.[status] = b.[status];

go
Run Code Online (Sandbox Code Playgroud)

如果查看最后一个查询,即两个表中 ID = 1 的记录,您会注意到 ID 值和状态都匹配;但是,只返回 1 条记录。

Pio*_*otr 5

回答您的问题:“就结果而言,这两个查询不是同义词吗?”

。你的两个连接都是左连接,所以你需要考虑 3 个场景:
1. 两个右表中的行都存在 -> 将产生相同的记录
2. 仅一个右表中的行存在 -> 联合将产生两行或更多行右表的一行 NULL 值和来自其他右表的匹配行。纯 JOIN 不会产生带有 NULL 的行。
3. 两个右表中的行不存在 -> 相同的结果(2 行由不同的组合)