2016-10-10 71 views
1

我有一個存儲過程的問題。我有一個郵件羣發服務3個表,我想知道有多少任務(表 - MMProcessItem)我仍然需要做...帶連接的T-SQL存儲過程

我有這3個表:

Tables

這裏是我的選擇:

SELECT 
    MMAddress.AddressID, MMProcess.ProcessID 
FROM 
    MMProcess, MMAddress 
LEFT OUTER JOIN 
    (SELECT * 
    FROM MMProcessItem) Items ON Items.AddressID = MMAddress.AddressID 
WHERE 
    Items.ResultID IS NULL 
ORDER BY 
    ProcessID, AddressID 

我的SQL代碼工作,如果沒有什麼MMProcessItem表罰款,這是我得到:

enter image description here

但是,如果我發送一封電子郵件,就像一個用AddressID = 1和的ProcessID = 1,我沒有得到了1個紀錄AddressID = 1和的ProcessID = 2,我應該得到一個總的3記錄,但我得到的是一個總的2條記錄...

enter image description here

很抱歉,如果這是一個業餘的錯誤,我不是使用T-SQL來工作,做這些類型的東西...

+7

[不良習慣踢:使用舊樣式的JOIN(http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/08/bad-habits-to-kick-using-old -style-joins.aspx) - 在ANSI - ** 92 ** SQL標準中,舊式*逗號分隔的表*樣式列表已替換爲* proper * ANSI'JOIN'語法(**超過20年**之前),其使用是不鼓勵的。你應該***絕對不是混合兩種風格! –

+0

更糟糕的是混合它們。通常工作,但沒有任何人AFAIK技術支持。 – RBarryYoung

回答

3

您加入MMProcessItem需要兩個謂詞,一個加入MMProcess, e加入MMAddress。您目前只加入MMAddress。這意味着,當你添加一條記錄與AddressID = 1和ProcessID = 1它同時刪除記錄,其中AddressID = 1,而不僅僅是一個記錄,其中AddressID爲1 ProcessID爲1

你可以重寫查詢如:

SELECT a.AddressID, p.ProcessID 
FROM MMProcess AS p 
     CROSS JOIN MMAddress AS a 
     LEFT OUTER JOIN MMProcessItem AS i 
      ON i.AddressID = a.AddressID 
      AND i.ProcessID = p.ProcessID 
WHERE i.ResultID IS NULL 
ORDER BY p.ProcessID, a.AddressID; 

注意使用顯式連接語法,也別名爲簡潔

由於您使用的是LEFT JOINMMProcessItem只是爲了刪除記錄,那麼你可能會發現使用NOT EXISTS表達的意圖更好,但更重要的是,it can also perform better

SELECT a.AddressID, p.ProcessID 
FROM MMProcess AS p 
     CROSS JOIN MMAddress AS a 
WHERE NOT EXISTS 
     ( SELECT 1 
      FROM MMProcessItem AS i 
      WHERE i.AddressID = a.AddressID 
      AND  i.ProcessID = p.ProcessID 
     ) 
ORDER BY p.ProcessID, a.AddressID; 
+0

謝謝!你救了我 ! :) – Pedro