2016-10-10 121 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