2016-05-30 253 views
1

我想加入使用contactno列,当我只运行dbo.contact查询SQL左连接返回更多的记录比预期

SELECT  
    contactno, date_recd 
FROM   
    dbo.contact 
WHERE  
    (date_recd > CONVERT(DATETIME, '2016-01-01 00:00:00', 102)) 
    AND (date_recd <= CONVERT(DATETIME, '2016-04-01 00:00:00', 102)) 

我得到11526条记录两个表dbo.contactdbo.notes但是当我加入notes

SELECT  
    dbo.contact.contactno, dbo.contact.date_recd, dbo.notes.noteline 
FROM   
    dbo.contact 
LEFT OUTER JOIN 
    dbo.notes ON dbo.contact.contactno = dbo.notes.contactno 
WHERE  
    (dbo.contact.date_recd > CONVERT(DATETIME, '2016-01-01 00:00:00', 102)) 
    AND (dbo.contact.date_recd <= CONVERT(DATETIME, '2016-04-01 00:00:00', 102)) 

然后我得到22276条记录。我不确定发生了什么问题。我只想得到所有11526如何做到这一点?任何帮助非常感谢。

+4

可能有不止一个'noteline'每'contactno' –

+0

@vkp但我问它只是给我所有的联络表中的列不应该只返回11526分的记录,并在它不存在它应该是空的吗? – CodeMan

+0

从查询中删除'noteline'并查看区别 –

回答

1

是的,执行左连接将返回第一个表中的所有行,并仅匹配第二个表中的行。但是,如果第二个表中的多行匹配,它将返回两个行,这会导致第一个表中的行重复。

例如:

Table1 
ID Value 
1  A 
2  B 
3  C 

Table2 
ID Value 
1  X 
1  Y 
2  Z 

Select * from Table1 a 
left join Table2 b 
on a.ID = b.ID 

返回:

ID Value ID Value 
1  A  1  X 
1  A  1  Y 
2  B  2  Z 
3  C Null Null 

其中共有四排,即使Table1在本例中只有三个。为了避免这种情况,您需要调整连接标准,以便每行最多只有一个匹配项,或者添加一些重复步骤。

2

如果你想每个联系人只有一个音符,你可以使用outer apply

SELECT c.contactno, c.date_recd, n.noteline 
FROM dbo.contact c OUTER APPLY 
    (SELECT TOP 1 n.* 
     FROM dbo.notes n 
     WHERE c.contactno = n.contactno 
    ) n 
WHERE (c.date_recd > CONVERT(DATETIME, '2016-01-01 00:00:00', 102)) AND 
     (dc.date_recd <= CONVERT(DATETIME, '2016-04-01 00:00:00', 102)); 

通常情况下,子查询将有一个ORDER BY,指明哪些注意你想要的。但是,您的查询并未指定多个注释中的哪一个是首选注释。

0

以上答案很棒,但我想发布解决我的问题的代码。所以我需要所有11526条记录,但不仅是每个联系人的前1条直线,我想要所有的条形码,所以我最终将记录连接到单个字符串。

Select contact.contactno, 
STUFF((Select '' + notes.noteline FROM notes 
Where notes.contactno = contact.contactno 
order by notes.contactno for xml path (''),type).value('.','nvarchar(max)'),1,2,'') AS Notes 
From contact 
WHERE 
(contact.date_recd > CONVERT(DATETIME, '2015-12-31 00:00:00', 102)) 
AND 
(contact.date_recd <= CONVERT(DATETIME, '2016-04-01 00:00:00', 102)) 
Group By contact.contactno;