FULL OUTER JOIN 期间 AND 和 WHERE 子句的行数差异

问题描述 投票:0回答:2

我有一个关于我想要由 2 个表组成的 FULL OUTER JOIN 的问题。

首先我有大约 10000 行的 PMCContract 表 然后我有大约 17000 行的 DirPartyTable

这些表可以通过键 PARTYID 连接在一起,您可以在两个表中找到该键。当我进行外部联接时,我最终得到 23000 行,因为并非 DIRPARTYTABLE 中的所有行都有合同(PMCContract 的唯一键)

现在让我困惑的是下面的事情。在 PMCCONTRACT 表中,我有一个字段 CONTRACTSTATUS (int),如果它被标记为“5”,我想完全将其省略。不应该加入。

以下语句给了我 23000 行,这似乎是正确的

SELECT
PMCCONTRACT.CONTRACTID
,PMCCONTRACT.CONTRACTSTATUS
,DIRPARTYTABLE.PARTYID

FROM PMCCONTRACT

FULL OUTER JOIN DIRPARTYTABLE
ON DIRPARTYTABLE.PARTYID = PMCCONTRACT.PARTYID
    AND PMCCONTRACT.CONTRACTSTATUS <> 5

但是当我尝试不同的代码时,当我决定只加入“5”时,它会给我 27000 行,而不是我期望的 17000 行(因为只有 8 个带有标签“5”的合约)。现在我也认为上面的结果不可信,因为使用“=”而不是“<>”不会显示相反的结果。

SELECT
PMCCONTRACT.CONTRACTID
,PMCCONTRACT.CONTRACTSTATUS
,DIRPARTYTABLE.PARTYID

FROM PMCCONTRACT

FULL OUTER JOIN DIRPARTYTABLE
ON DIRPARTYTABLE.PARTYID = PMCCONTRACT.PARTYID
    AND PMCCONTRACT.CONTRACTSTATUS = 5

于是我想我们可以使用 WHERE 子句来代替(但是,由于我连接了多个表,所以我不确定是否可以使用它)。这给了我大约 10000 行,这显然是不够的。

SELECT
PMCCONTRACT.CONTRACTID
,PMCCONTRACT.CONTRACTSTATUS
,DIRPARTYTABLE.PARTYID

FROM PMCCONTRACT

FULL OUTER JOIN DIRPARTYTABLE
ON DIRPARTYTABLE.PARTYID = PMCCONTRACT.PARTYID
    WHERE PMCCONTRACT.CONTRACTSTATUS <> 5

现在,当我选择 '=5' 与 WHERE 子句结合时,它确实给出了我所期望的 8。

SELECT
PMCCONTRACT.CONTRACTID
,PMCCONTRACT.CONTRACTSTATUS
,DIRPARTYTABLE.PARTYID

FROM PMCCONTRACT

FULL OUTER JOIN DIRPARTYTABLE
ON DIRPARTYTABLE.PARTYID = PMCCONTRACT.PARTYID
    WHERE PMCCONTRACT.CONTRACTSTATUS = 5

到目前为止我的结论是 - 看来“AND 和 <>”的组合给了我正确的数据 -“AND 和=”的组合给了我不正确的数据 - 'WHERE 和 <>' 的组合给了我不正确的数据 - 'WHERE 和 =' 的组合给了我正确的数据

我显然错过了一些明显的东西,但我希望你们中的一些人能够启发我!

亲切的问候, 广告

sql sql-server
2个回答
1
投票

使用

FULL JOIN
的过滤条件完全令人困惑。

我的建议是在子查询中进行过滤:

SELECT c.CONTRACTID, c.CONTRACTSTATUS, dp.PARTYID
FROM (SELECT c.*
      FROM PMCCONTRACT c
      WHERE c.CONTRACTSTATUS <> 5
     ) c FULL OUTER JOIN
     DIRPARTYTABLE dp
     ON dp.PARTYID = c.PARTYID

0
投票

我认为你应该考虑到

PMCCONTRACT
以及因此
CONTRACTSTATUS
不存在这一事实。所以更换条件

WHERE PMCCONTRACT.CONTRACTSTATUS = 5

WHERE (PMCCONTRACT.CONTRACTSTATUS is null OR PMCCONTRACT.CONTRACTSTATUS = 5) 

WHERE PMCCONTRACT.CONTRACTSTATUS <> 5 

WHERE (PMCCONTRACT.CONTRACTSTATUS is null OR PMCCONTRACT.CONTRACTSTATUS <> 5)
© www.soinside.com 2019 - 2024. All rights reserved.