2016-05-30 8 views
1
erwartet

Ich versuche, zwei Tabellen zu verknüpfen dbo.contact und dbo.notes die contactno Spalte, wenn ich nur die Abfrage für dbo.contact laufenSQL LEFT JOIN mehrere Datensätze Rückkehr als

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)) 

I 11526 Aufzeichnungen erhalten, aber wenn ich verbinden sie es mit dem notes Tisch

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)) 

dann 22.276 Datensätze ich erhalte. Ich bin mir nicht sicher, was falsch läuft. Ich möchte nur alle 11526 bekommen, wie man das macht? Jede Hilfe wird sehr geschätzt, danke.

+4

kann es mehr als eine sein 'noteline' pro' contactno' –

+0

@vkp aber ich bitte geben Sie mir nur alle Spalten von Kontakttabelle sollte es nicht nur 11.526 Datensätze zurück, und wo es nicht der Fall ist existiert es sollte null sein oder ?? – CodeMan

+0

entfernen 'noteline' aus der Abfrage und sehen den Unterschied –

Antwort

1

Ja, wenn Sie einen linken Join ausführen, werden alle Zeilen der ersten Tabelle und nur die übereinstimmenden Zeilen der zweiten Tabelle zurückgegeben. Wenn jedoch mehr als eine Zeile aus der zweiten Tabelle übereinstimmt, werden beide zurückgegeben, was zu einer Duplizierung der Zeilen in der ersten Tabelle führen kann.

Zum Beispiel:

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 

Returns:

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

der insgesamt vier Reihen hat, obwohl Table1 im Beispiel nur drei. Um dies zu vermeiden, müssen Sie entweder Ihre Join-Kriterien so anpassen, dass jede Zeile höchstens eine Übereinstimmung aufweist, oder einige Unduplizierungsschritte hinzufügen.

2

Wenn Sie nur eine Note pro Kontakt möchten, können Sie outer apply verwenden:

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)); 

Normalerweise wird die Unterabfrage würde eine ORDER BY haben, angeben, welche Sie beachten möchten. Ihre Abfrage gibt jedoch nicht an, welche der mehreren Notizen die bevorzugte ist.

0

Die obigen Antworten waren fantastisch, aber ich wollte den Code, der mein Problem behoben. Also brauchte ich alle 11526 Datensätze, aber nicht nur die oberste 1 nicht für jeden Kontakt Ich wollte alle Notelines, so endete ich die Verkettung der Datensätze zu einer einzigen Zeichenfolge.

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;