带连接的T-SQL存储过程

时间:2016-10-10 16:32:57

标签: sql-server tsql

我的存储过程有问题。我有3个表用于群发邮件服务,我想知道我还需要做多少任务(表 - MMProcessItem)...

我有这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

如果MMProcessItem表中没有任何内容,我的SQL代码工作正常,这就是我得到的:

enter image description here

但是,如果我发送1封电子邮件,例如AddressID = 1且ProcessID = 1的电子邮件,我不再获得AddressID = 1且ProcessID = 2的1条记录,我应该总共得到3条记录,但是我得到的是总共2条记录......

enter image description here

对不起,如果这是一个业余的错误,我不习惯使用t-sql并做这些类型的事情......

1 个答案:

答案 0 :(得分:3)

您与MMProcessItem的加入需要两个谓词,一个加入MMProcess,另一个加入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可以更好地传达意图,但更重要的是,{{3} }。

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;