Sql 条件连接
我正试图实现这样的条件连接Sql 条件连接,sql,sql-server,Sql,Sql Server,我正试图实现这样的条件连接 declare @JoinWithT2 bit = 1; select T1.* from T1 inner join T2 on (@JoinWithT2 = 0 or T1.Id=T2.Id) 这很好,当我传递@JoinWithT2值1时,它使用两个表的联接给出结果,当我传递@JoinWithT2值0时,它返回T1忽略联接的所有结果 这一切都很好,但我担心的性能,因为上述也可以实现像这样 if @JoinWithT2=0 begin select T
declare @JoinWithT2 bit = 1;
select T1.* from T1
inner join T2 on (@JoinWithT2 = 0 or T1.Id=T2.Id)
这很好,当我传递@JoinWithT2
值1时,它使用两个表的联接给出结果,当我传递@JoinWithT2
值0时,它返回T1忽略联接的所有结果
这一切都很好,但我担心的性能,因为上述也可以实现像这样
if @JoinWithT2=0
begin
select T1.* from T1
end
else
begin
select T1.* from T1
inner join T2 on (T1.Id=T2.Id)
end
实现条件连接的最佳方法是第一种还是第二种
我个人认为第二个查询的性能应该更好,因为它根本不涉及T2,而第一个查询可能使用T2,我感到困惑。根据
JoinWithT2
的值,以下操作应执行笛卡尔乘积或内部联接:
declare @JoinWithT2 bit = 1;
select T1.*
from T1 inner join
T2
on (@JoinWithT2 = 0 or T1.Id=T2.Id);
当@JoinWithT2
为0
时,on
子句始终为真。这使得连接
相当于交叉连接
以下是执行联接或获取第一个表的条件逻辑:
declare @JoinWithT2 bit = 1;
select T1.*
from T1 left outer join
T2
on (@JoinWithT2 = 1 and T1.Id=T2.Id)
where @JoinWithT2 = 0 or T2.Id is not null;
从性能角度来看,
if
中的单独语句通常会表现得更好。还有更多信息可供SQL引擎优化。但是,如果您在T2(id)
上有一个索引,那么相对于查询的其他部分(例如将结果返回给用户),性能差异可能并不显著。我感到困惑。根据JoinWithT2
的值,以下操作应执行笛卡尔乘积或内部联接:
declare @JoinWithT2 bit = 1;
select T1.*
from T1 inner join
T2
on (@JoinWithT2 = 0 or T1.Id=T2.Id);
当@JoinWithT2
为0
时,on
子句始终为真。这使得连接
相当于交叉连接
以下是执行联接或获取第一个表的条件逻辑:
declare @JoinWithT2 bit = 1;
select T1.*
from T1 left outer join
T2
on (@JoinWithT2 = 1 and T1.Id=T2.Id)
where @JoinWithT2 = 0 or T2.Id is not null;
从性能角度来看,
if
中的单独语句通常会表现得更好。还有更多信息可供SQL引擎优化。但是,如果您在T2(id)
上有一个索引,那么相对于查询的其他部分,性能差异可能并不显著,例如,将结果返回给用户。在这种情况下,最好的选择可能是使用动态SQL,尽管新版本的SQL server中的or条件没有旧版本的SQL server中的or条件差。if语句很好,但是在添加了两个或三个其他表之后就很难维护了,这些表可能会连接,也可能不会连接,这取决于特定的条件。随着时间的推移,or条件可能会变慢,并且会向查询中添加更多内容。构建一个搜索类型的查询,只包含这组特定参数所需的内容,通常是最佳选择
您可能想阅读:
或者(如果您使用的是SQL SERVER 2005或更早版本)
在这种情况下,最好的选择可能是使用动态SQL,尽管新版本SQL server中的or条件没有旧版本SQL server中的or条件那么糟糕。if语句很好,但是在添加了两个或三个其他表之后就很难维护了,这些表可能会连接,也可能不会连接,这取决于特定的条件。随着时间的推移,or条件可能会变慢,并且会向查询中添加更多内容。构建一个搜索类型的查询,只包含这组特定参数所需的内容,通常是最佳选择 您可能想阅读: 或者(如果您使用的是SQL SERVER 2005或更早版本)
如果没有从T2中选择任何内容,为什么需要加入?同样,可以通过以下方式实现:
select T1.*
from T1
where @JoinWithT2 = 0 or T1.Id in (select T2.Id from T2);
如果没有从T2中选择任何内容,为什么需要联接?同样,可以通过以下方式实现:
select T1.*
from T1
where @JoinWithT2 = 0 or T1.Id in (select T2.Id from T2);
它不会忽略连接。它总是与桌子相连。如果JoinWithT2=1,则它执行正确的联接(在ID上),如果它为0,则联接所有记录,有效地将联接转换为交叉联接。这就是您想要的吗?请注意,如果
@JoinWithT2
为0,则第一个查询并不等同于select T1.*from T1
——相反,它变成了一个隐式笛卡尔连接-请参见“是”。实际上,如果@JoinWithT2
值为0,我想忽略连接。您确实需要定义“忽略连接”的含义。您的两个代码片段不会给出相同的结果。它不会忽略连接。它总是与桌子相连。如果JoinWithT2=1,则它执行正确的联接(在ID上),如果它为0,则联接所有记录,有效地将联接转换为交叉联接。这就是您想要的吗?请注意,如果@JoinWithT2
为0,则第一个查询并不等同于select T1.*from T1
——相反,它变成了一个隐式笛卡尔连接-请参见“是”。实际上,如果@JoinWithT2
值为0,我想忽略连接。您确实需要定义“忽略连接”的含义。您的两个代码片段不会给出相同的结果。