0

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

因此,我将在 Id 和名称上加入我的第二个表,并尝试将其放到仅当 IdNumber 不匹配时才加入名称的位置。

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

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

所以它是因为他们的 id 匹配而拉最后 2 个,但也因为他们的 id 不匹配并且他们的名字匹配而加入前 2 个,但是为什么它甚至要加入前 2 个呢?我怀疑它在决定加入哪里时会忽略 != 语句,因为其他条件都已满足,但我希望它以某种方式考虑这个 != 语句。

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

(*编辑)对不起,我应该正确命名这些 - 我已经修改了名称。并且完整的外部连接是必要的,无论如何我都需要两个表中的所有内容并且它工作正常,但感谢您的建议。

4

3 回答 3

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  
于 2013-01-11T16:07:01.203 回答
0

如果列来自正确的表,您的查询应该可以工作。因为您没有使用表别名,所以我怀疑您有一个表达式,例如:

fname1 = fname2

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

fname1 = fname1

这基本上总是 TRUE(除非 fname1 不为空)。

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

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
于 2013-01-11T16:11:24.427 回答
0

考虑到在一个 JOIN 中这样做会有多混乱,我建议使用临时表来保存关系。

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

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

于 2013-01-11T16:16:35.167 回答