左外连接查询在SQL Server中返回重复项

时间:2014-07-18 02:05:27

标签: sql duplicates left-join

我有一个表1(MID, SSN, ...MID是主键,表2(ID, SSN, StateCode..)其中IDSSN构成主键。我正在尝试显示表1中的所有列以及表2中与StateCode匹配的SSN。 Tbl 1有50行,有些具有相同的SSN值。

如果在表2中找不到SSN匹配,则在StateCode中显示NULL是可以接受的,所以我选择了左连接。这是我的查询

Select 
    tbl1.*, tbl2.StateCode
from 
    tbl1
left outer join 
    tbl2 on tbl1.SSN = tbl2.SSN

我想要检索50条记录,但是我得到70条,在tbl1中包含相同ssn值的行最终会在最终输出中重复。出了什么问题?

6 个答案:

答案 0 :(得分:3)

我建议你阅读cartesian product

如果第一个表中有50行,而第二个表中有70行,则表示3500行。连接条件tbl1.SSN = tbl2.SSN将过滤掉行,但最终可能会超过50行。

回到你的问题,你可以通过尝试以下方法看到发生了什么:

SELECT 
  tbl1.*,
  (SELECT COUNT(*) FROM tbl2 WHERE tbl1.SSN = tbl2.SSN) AS NbResultTbl2
FROM 
  tbl1

这将告诉tbl1中哪些tbl2行有多个匹配。如果NbResultTbl2列中的数字大于1,那么您最终会得到重复项。

要消除这些重复项,您可以尝试:

SELECT 
  tbl1.*,
  (SELECT TOP 1 StateCode FROM tbl2 WHERE tbl1.SSN = tbl2.SSN) 
FROM 
  tbl1  

这将获得tbl2中匹配的SNN的第一个StateCode

答案 1 :(得分:0)

尝试使用SELECT DISTINCT而不仅仅是SELECT语句,SELECT DISTINCT不会显示重复项

答案 2 :(得分:0)

通过pixelbits添加评论。您可以使用(跳过MID)

执行子查询
 select distinct ssn,* from tbl1

然后将其加入tbl2

除非MID之外的其他列是不同的

,否则应该给出50行

答案 3 :(得分:0)

评论太长了。

" ID和SSN都是主键" 。 。 。该声明表明缺乏对主键的理解。一个表只能有一个主键。主键可以是复合的(由多个列组成),但只有一个。

如果MID是table1的主键,那么可能多行可以具有相同的SSN。

您的查询是:

Select *
from tbl1, tbl2.StateCode
from tbl1, tbl2 left outer join tbl2 on tbl1.SSN = tbl2.SSN

这甚至不是有效的SQL。您可以尝试这个版本:

Select distinct tbl1.*, tbl2.StateCode
from tbl1 left outer join
     tbl2
     on tbl1.SSN = tbl2.SSN;

这是有效的,看起来像你想要的。

答案 4 :(得分:0)

尝试在Table2中对SSN进行分组并获取MAX StateCode:

SELECT Table1.*, DT.StateCode
FROM Table1
LEFT OUTER JOIN (
    SELECT SSN, MAX(StateCode) AS StateCode FROM Table2 GROUP BY SSN
) DT ON Table1.SSN = DT.SSN

答案 5 :(得分:0)

尝试, 你的两个表都有一个主键就在那里所以只需尝试ID列匹配

Select tbl1.MID,tbl1.SSN, tbl2.StateCode
from tbl1
left outer join tbl2 
on tbl1.MID= tbl2.ID
Group by tbl1.MID,tbl1.SSN, tbl2.StateCode