【问题标题】:Additional "Or-Criteria" in the ON-Clause of an inner join内部连接的 ON 子句中的附加“或标准”
【发布时间】:2011-09-14 15:05:34
【问题描述】:

On-Clause-Criteria 依赖于两列中的任何一个时,(内部)连接两个表的正确方法是什么?所以 Table1 应该在两列之一等于 Table2 的一列时加入。

查看以下简化的 T-SQL 以了解我的意思以及我是否以正确的方式完成了它:

SET TRANSACTION ISOLATION LEVEL READ COMMITTED
GO
BEGIN TRANSACTION;
GO
create table #RMA1(
    SSN_IN varchar(15),
    SSN_OUT varchar(15)
)
create table #RMA2(
    SSN_NUMBER varchar(15),
)
INSERT INTO #RMA1 VALUES('012590001827977', '351600035840752');
INSERT INTO #RMA1 VALUES('332653577440220', '351600035804105');
INSERT INTO #RMA1 VALUES('350302031074780', '350302031074780');
INSERT INTO #RMA1 VALUES('351649036778024', '351806033440194');

INSERT INTO #RMA2 VALUES('012590001827977');
INSERT INTO #RMA2 VALUES('332653577440220');
INSERT INTO #RMA2 VALUES('350302031074780');
INSERT INTO #RMA2 VALUES('351649036778024');
INSERT INTO #RMA2 VALUES('351600035840752');
INSERT INTO #RMA2 VALUES('351600035804106');

SELECT SSN_IN,SSN_OUT,SSN_NUMBER FROM #RMA1 INNER JOIN
#RMA2 ON (#RMA1.SSN_IN = #RMA2.SSN_NUMBER OR
          #RMA1.SSN_Out = #RMA2.SSN_NUMBER)

DROP TABLE #RMA1;
DROP TABLE #RMA2;
GO
COMMIT TRANSACTION;
GO

结果:

SSN_IN          SSN_OUT            SSN_NUMBER
012590001827977 351600035840752    012590001827977
012590001827977 351600035840752    351600035840752
332653577440220 351600035804105    332653577440220
350302031074780 350302031074780    350302031074780
351649036778024 351806033440194    351649036778024

问:那么在ON-内连接子句中使用OR 连接表是否正确?

它确实正确返回了 5 条记录并删除了 #RM2 的最后一条记录,因为它既不在 #RM1.SSN_IN 也不在 #RM1.SSN_OUT 中。但我感觉很糟糕,这并不总是给出正确的结果。实际上真正的完整查询的性能很差。

【问题讨论】:

    标签: sql-server-2005 tsql join


    【解决方案1】:

    结果应该是正确的,但是你的观察是正确的,性能很差。数据库不能有效地使用索引,因为它必须扫描索引并对每个项目进行算术运算。

    改为使用两个左连接可以让数据库更好地利用索引:

    select
      SSN_IN,
      SSN_OUT,
      coalesce(T1.SSN_NUMBER, T2.SSN_NUMBER) as SSN_NUMBER
    from
      #RMA1
      left join #RMA2 as T1 on #RMA1.SSN_IN = T1.SSN_NUMBER
      left join #RMA2 as T2 on #RMA1.SSN_Out = T2.SSN_NUMBER
    where
      T1.SSN_NUMBER is not null or T2.SSN_NUMBER is not null
    

    【讨论】:

      猜你喜欢
      • 2011-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-03
      • 2018-10-06
      • 1970-01-01
      • 2016-08-17
      • 1970-01-01
      相关资源
      最近更新 更多