加入((=声明)或((!=声明),其他规定))

时间:2013-01-11 16:01:47

标签: sql sql-server

我有一些信息,其中IdNumbers(不是主键ID,只是分配给个人的随机ID)在我的第一个表中并不总是正确的。

因此,我在Ids和名称上加入我的第二个表,并尝试将它连接到只有在IdNumbers不匹配时它才会加入名称的位置。

我正在使用大致如下的连接语句进行查询(我忽略了SELECT,WHERE和ORDER BY部分,因为我相信它们对这个问题没有影响而且我不喜欢我想让人感到困惑,因为它们非常复杂 - 如果下面的查询部分应该像我想要的那样工作而且问题显然在其他地方,那么就告诉我,这将回答我的问题):< / p>

FROM Table1
FULL OUTER JOIN Table2 ON ((Table1.IdNumber = Table2.IdNumber) 
OR (Table1.IdNumber != Table2.IdNumber 
    AND Table1.Lname = Table2.Lname 
    AND Table1.Fname = Table2.Fname))

但是,它会加入那些同时具有匹配ID和匹配名称的人,如下所示:

Fname   M   Lname   Table1.IdNumber  Table2.IdNumber2
Matthew -   Smith   1                2
Matthew H   Smith   2                1
Matthew -   Smith   1                1
Matthew H   Smith   2                2

所以它拉动了最后2个,因为它们的id匹配,但也加入了前2个,因为它们的id不匹配且名称匹配,但为什么它甚至加入前2个?我怀疑它在决定加入的地方时会忽略!=语句,因为其他条件已经完成,但我希望以某种方式考虑这个!=语句。

如果这应该有效,就像我之前说过的那样,请告诉我,它会回答我的问题。

(* EDIT) 对不起,我应该正确地命名这些 - 我已经修改了名字。完整的外部连接是必要的,我需要两个表中的所有内容,无论什么,它工作正常,但谢谢你的建议。

3 个答案:

答案 0 :(得分:0)

我想你想要这样的东西:

select t1.*,t2.*  
from t1,t2  
where  t1.id = t2.id  
and  t1.name = t2.name
union  
select t1.*,t2.*  
from t1,t2  
where  t1.id ! t2.id  

答案 1 :(得分:0)

如果列来自右表,则查询应该有效。因为您没有使用表别名,所以我怀疑您有一个表达式,例如:

fname1 = fname2

并且两列都在同一个表中。或者更糟:

fname1 = fname1

基本上始终为TRUE(除非fname1不为null)。

您的查询可能有效,但在大多数数据库中效率很低,因为它们将使用嵌套循环优化。考虑将查询重写为:

from table1 t1 full outer join
     table2 byID
     on t1.IdNumber = byID.IdNumber full outer join
     table2 byName
     on t1.fname = byName.fname and t1.lname = byName.lname and t1.idNumber <> byName.idNumber

这将需要更改查询中的其他子句,通常是:

coalesce(byId.column, byName.column) as Column

答案 2 :(得分:0)

考虑到在一个JOIN中这将是多么混乱,我建议使用临时表来保持关系。

您可以将第一个表中的所有ID插入临时表,然后执行两次传递以更新包含第二个表ID的列 - 首先使用ID匹配的位置,第二个使用ID不匹配的位但名字确实如此。

然后,您可以使用此表连接这两个表,从表2中为表1中的每个记录检索最多一条记录。