我正在尝试使用dbo.contact
列加入两个表dbo.notes
和contactno
,当我只运行dbo.contact的查询时
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条记录,但当我加入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如何做到这一点?非常感谢任何帮助。
答案 0 :(得分: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
,指定您想要的注释。但是,您的查询并未指定多个注释中的哪一个是首选注释。
答案 1 :(得分: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 :(得分:0)
上面的答案很神奇,但我想发布修复我的问题的代码。所以我需要所有的11526条记录,但不仅是每个联系人的前1个noteline我想要所有的notelines所以我最终将记录连接成一个字符串。
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;