2016-04-22 70 views
0

我有以下查詢加盟:LEFT JOIN未與單個記錄

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 

我使用查詢其導入到我的數據庫的表之前將數據導入從另一個數據庫(fm_stg.classByStudent_termData_assessmentData)一個臨時表。此特定查詢是將數據導入到與termData相關的多個表中的較大存儲過程的一部分。

當我運行sproc時,我得到的記錄插入到fm_stg.classByStudent_termData_assessmentData中,但沒有插入到termData中。當我遇到這個問題時,我只插入一條記錄,但它適用於我之前做過的10,000條記錄。我使用左連接來確定我的數據庫表中已經存在的內容以及哪些內容不存在,然後從暫存表中獲取相關記錄。然而,有了這個記錄:

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

該select返回什麼 - 爲什麼是這樣的?該記錄絕對不存在於我的termData表中,並將記錄插入到登臺表中的所有其他表中。 sproc在事務中運行所有的插入操作,以避免這種情況下記錄被插入到某些表中而不是其他的表中,但似乎並不奏效。

+0

那麼,沒有得到記錄的唯一原因應該是'WHERE'子句。刪除它並運行已更改的選擇查詢來查看您意外獲得的內容。 –

+0

你能創建一個SQL小提琴來重現這個問題嗎?我沒有看到任何錯誤的查詢。 –

+0

@TabAlleman我試着在SQL Fiddle(我以前沒用過)中創建它,但不能爲我的生活讓它做任何事情,例如,創建一個表。編輯:它似乎沒有在Firefox中工作...將創建一個演示。 – Ben

回答

1

您說查詢對先前的10,000條記錄起作用,但不適用於當前的記錄。在查詢中唯一看起來很奇怪的是ON子句中的第三行,您將字段(studentID)與自身進行比較。

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 

我只是猜測這裏,但因爲這條線ON子句中,你要比較的學生證,太?所以可能你很幸運,查詢工作到目前爲止,現在你偶然發現了學生證。我猜想ON條款應該是這樣的:

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 

順便說一句,查詢獲得更具可讀性通過使用表的別名。在下面的查詢我使用adfm_stg.classByStudent_termData_assessmentDatatdtermData

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; 

而且對於生存確認的時候,你爲什麼要使用反連接把戲?您是否有直接的問題NOT EXISTS?只有在真正需要時才使用技巧。該查詢讀更好如下:

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

隨着你甚至可以使用了NOT IN另一個DBMS(即Where (class_code, termId, studenId) Not In (Select ...)),這是不相關的,從而爲你甚至不能發生這樣的錯字,但SQL Server不功能不幸的是,IN條款中的元組。

+0

我沒有特別好的理由使用'反加入'技巧,除了熟悉之外 - 感謝您提出其他建議。我認爲「不存在」的表現更好?我認爲我遇到的問題是該記錄插入到大量相關表中,但未插入到'termData'表中。我仍然不明白爲什麼這是從我的sproc,但如果我刪除相關表中的所有記錄,它似乎工作。這首先打破了我的來源(不是我的鏈接服務器/數據庫)的不良記錄。謝謝你的幫助。 – Ben