我有一个表1(MID, SSN, ...
)MID
是主键,表2(ID, SSN, StateCode..
)其中ID
和SSN
构成主键。我正在尝试显示表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值的行最终会在最终输出中重复。出了什么问题?
答案 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