假设我们有以下查询
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 条记录。
回答您的问题:“就结果而言,这两个查询不是同义词吗?”
不
。你的两个连接都是左连接,所以你需要考虑 3 个场景:
1. 两个右表中的行都存在 -> 将产生相同的记录
2. 仅一个右表中的行存在 -> 联合将产生两行或更多行右表的一行 NULL 值和来自其他右表的匹配行。纯 JOIN 不会产生带有 NULL 的行。
3. 两个右表中的行不存在 -> 相同的结果(2 行由不同的组合)