2016-04-22 6 views
0

ich die folgende Abfrage haben:LEFT JOIN Beitritt nicht mit einem einzelnen Datensatz

Insert into cet_database.dbo.termData 
    (
     termID, 
     studentID, 
     course, 
     [current], 
     program, 
     StbyCurrentClassID, 
     class, 
     classCode, 
     cancelled 
    ) 
    Select 
     fm_stg.classByStudent_termData_assessmentData.termID, 
     fm_stg.classByStudent_termData_assessmentData.studentID, 
     fm_stg.classByStudent_termData_assessmentData.class_code, 
     case when fm_stg.classByStudent_termData_assessmentData.[current] = 'Yes' then 1 else 0 end, 
     fm_stg.classByStudent_termData_assessmentData.program, 
     fm_stg.classByStudent_termData_assessmentData.classByStudentID, 
     fm_stg.classByStudent_termData_assessmentData.class, 
     fm_stg.classByStudent_termData_assessmentData.classID, 
     case when fm_stg.classByStudent_termData_assessmentData.cancelled_flag = 1 then 1 else 0 end 
From fm_stg.classByStudent_termData_assessmentData left outer join termData 
    On fm_stg.classByStudent_termData_assessmentData.class_code = termData.course 
    and fm_stg.classByStudent_termData_assessmentData.termID = termData.termID 
    and fm_stg.classByStudent_termData_assessmentData.studentID = fm_stg.classByStudent_termData_assessmentData.studentID 
Where termData.StbyCurrentClassID is null 

Ich verwende die Abfrage von Daten in eine Staging-Tabelle aus einer anderen Datenbank zu importieren (fm_stg.classByStudent_termData_assessmentData), bevor es in meiner Datenbank die Tabellen importieren. Diese bestimmte Abfrage ist Teil einer größeren gespeicherten Prozedur, die Daten in mehrere Tabellen importiert, die sich auf termData beziehen.

Wenn ich den Sproc ausführen, bekomme ich den Datensatz in fm_stg.classByStudent_termData_assessmentData eingefügt, aber nicht in termData. Ich füge nur einen Datensatz ein, wenn ich dieses Problem habe, aber es funktioniert für die 10.000 Datensätze, die ich zuvor gemacht habe. Ich verwende den linken Join, um festzustellen, was bereits in der Tabelle meiner Datenbank vorhanden ist und was nicht, und nehme dann die relevanten Datensätze aus der Staging-Tabelle. Jedoch mit diesem Datensatz:

316a, 39520, DEC 10, Yes, DEC10, 105713, DEC 10 (18), 6078, NULL, 2 

Die Auswahl gibt nichts zurück - warum ist das? Der Datensatz existiert definitiv nicht in meiner termData Tabelle und Datensätze einfügen in alle meine anderen Tabellen aus der Staging-Tabelle. Der Sproc führt alle Einfügungen in einer Transaktion aus, um genau dieses Szenario zu vermeiden, in dem Datensätze in einigen Tabellen und nicht in anderen Tabellen eingefügt werden, aber es scheint nicht zu funktionieren.

+0

Nun, der einzige Grund, den Datensatz nicht zu erhalten, sollte die WHERE-Klausel sein. Entfernen Sie es und führen Sie die geänderte Auswahlabfrage aus, um zu sehen, was Sie unerwartet erhalten. –

+0

Können Sie eine SQL-Fiddle erstellen, die das Problem reproduziert? Ich sehe nichts falsch mit der Abfrage. –

+0

@TabAlleman Ich habe versucht, es in SQL Fiddle zu erstellen (was ich vorher nicht verwendet habe), aber kann nicht für das Leben von mir bekommen es zu tun, z. Erstelle eine Tabelle. BEARBEITEN: es scheint nicht in Firefox zu funktionieren ... wird eine Demo erstellen. – Ben

Antwort

1

Sie sagen, die Abfrage arbeitete für die vorherigen 10.000 Datensätze, aber nicht für die aktuelle. Die einzige Sache, die in Ihrer Frage merkwürdig aussieht, ist die dritte Zeile in Ihrer Klausel, in der Sie ein Feld (das studentID) mit sich selbst vergleichen.

On fm_stg.classByStudent_termData_assessmentData.class_code = termData.course 
and fm_stg.classByStudent_termData_assessmentData.termID = termData.termID 
and fm_stg.classByStudent_termData_assessmentData.studentID = fm_stg.classByStudent_termData_assessmentData.studentID 

Ich kann nur raten hier, aber wie diese Linie ist in der ON Klausel, wollten Sie den Studentenausweis vergleichen, auch? So mag es sein, dass du nur Glück gehabt hast, dass die Abfrage so weit ging und du jetzt auf den Studentenausweis stößt. Ich nehme an, die ON Klausel sollte wie folgt aussehen:

On fm_stg.classByStudent_termData_assessmentData.class_code = termData.course 
and fm_stg.classByStudent_termData_assessmentData.termID = termData.termID 
and fm_stg.classByStudent_termData_assessmentData.studentID = termData.studentID 

By the way, Anfragen bekommen mehr lesbar Tabelle Aliase. In der folgenden Abfrage verwende ich ad für fm_stg.classByStudent_termData_assessmentData und td für termData:

Insert into cet_database.dbo.termData 
(
    termID, 
    studentID, 
    course, 
    [current], 
    program, 
    StbyCurrentClassID, 
    class, 
    classCode, 
    cancelled 
) 
Select 
    ad.termID, 
    ad.studentID, 
    ad.class_code, 
    case when ad.[current] = 'Yes' then 1 else 0 end, 
    ad.program, 
    ad.classByStudentID, 
    ad.class, 
    ad.classID, 
    case when ad.cancelled_flag = 1 then 1 else 0 end 
From fm_stg.classByStudent_termData_assessmentData ad 
Left Outer Join termData td On ad.class_code = td.course 
          And ad.termID  = td.termID 
          And ad.studentID = td.studentID 
Where td.StbyCurrentClassID is null; 

Darüber hinaus, wenn die Existenz Überprüfung, warum verwenden Sie den Trick anti-Mitglied werden? Hattest du Probleme mit einem einfachen NOT EXISTS? Verwenden Sie Tricks nur, wenn sie wirklich benötigt werden. Die Abfrage liest besser wie folgt:

Insert into cet_database.dbo.termData 
(
    termID, 
    studentID, 
    course, 
    [current], 
    program, 
    StbyCurrentClassID, 
    class, 
    classCode, 
    cancelled 
) 
    Select 
    termID, 
    studentID, 
    class_code, 
    case when [current] = 'Yes' then 1 else 0 end, 
    program, 
    classByStudentID, 
    class, 
    classID, 
    case when cancelled_flag = 1 then 1 else 0 end 
    From fm_stg.classByStudent_termData_assessmentData ad 
    Where Not Exists 
    (
    Select * 
    From termData td 
    Where ad.class_code = td.course 
     And ad.termID  = td.termID 
     And ad.studentID = td.studentID 
); 

mit einem anderen DBMS Sie auch NOT IN genutzt haben könnte (dh Where (class_code, termId, studenId) Not In (Select ...)), die nicht so solchen Tippfehler korreliert ist wie Sie konnte nicht einmal aufgetreten sind, aber SQL Server nicht Feature Tupel in der IN Klausel leider.

+0

Ich benutze den "Anti-Join" -Trick ohne besonderen Grund, außer Vertrautheit - danke, dass Sie etwas anderes vorgeschlagen haben. Ich nehme an, dass die Leistung von "Not Exists" besser ist? Ich denke, das Problem, das ich hatte, war, dass der Datensatz in eine ganze Reihe verwandter Tabellen eingefügt wurde, aber nicht in die 'termData'-Tabelle. Ich verstehe immer noch nicht wirklich, warum das von meinem Sproc ist, aber wenn ich alle Datensätze in den zugehörigen Tabellen lösche, scheint es zu funktionieren. Dies brach an erster Stelle wegen einer schlechten Aufzeichnung von meiner Quelle (ein Verbindungsserver/eine Datenbank, die nicht meine ist). Danke für Ihre Hilfe. – Ben