如何反转 SQL 中的连接条件?

How do I invert my join critera in TSQL?

我认为这是SQL中比较基本的操作,但我很难搞清楚。

我有两个 table,一个源 table 我正在尝试 SELECT 我的数据,一个参考 table 包含序列号和交易 #'s(来源 table 也有这些列,等等)。我想做两种不同的 SELECT,一种是 serial/trans 数字对存在于源 table 中,另一种是 serial/trans 数字不存在。 (序列号和转号的组合是这两个table的主键)

最初我是通过这样的连接来做到这一点的:

SELECT * FROM source s
INNER JOIN reference r ON s.serial = r.serial AND s.trans = r.trans

我认为这应该会给我来源 table 中的所有内容,其中 serial/trans 对与参考 table 中的一对匹配。我不确定这是正确的,但它返回了合理数量的结果,我认为它看起来不错。

当我去做相反的事情时,从 serial/trans 对与参考中的一对不匹配的来源获取所有内容时,我遇到了问题。我尝试了以下查询:

SELECT * FROM source s
INNER JOIN reference r ON s.serial <> r.serial AND s.trans <> r.trans

当我 运行 这个查询永远持续下去时,它开始返回比应有的结果更多的结果,比整个源 table 中的实际结果要多。它最终以 OOM 异常结束,我让它 运行 持续 20 分钟以上。从某些角度来看,我正在处理的来源 table 有大约 1300 万条记录,而参考文献 table 有大约 105,000 条。

那么我如何获得我正在寻找的结果呢?如果还不清楚,第一个查询的结果数 + 第二个查询的结果数应该等于我源中的记录总数 table.

感谢您的帮助!

"LEFT JOIN" 匹配匹配在一起的记录,return NULL 匹配不匹配的记录。

因此,不匹配的记录在来自引用 table 的列中都为 NULL。这样,您就可以向 return 添加 where 子句,仅在 table "reference" 的非可空列(如主键)中具有空值的记录。

SELECT * FROM source s
LEFT JOIN reference r ON s.serial = r.serial AND s.trans = r.trans
WHERE R.serial IS NULL 

我想你需要类似 NOT EXISTS:

SELECT * 
FROM source s
WHERE NOT EXISTS (SELECT 1
                  FROM reference r 
                  WHERE s.serial = r.serial AND s.trans = r.trans)

以上查询将从 source 中获取所有内容,其中 serial/trans 对与 reference.

中的一对不匹配

正如下面@Dan 的评论中所引用的那样,NOT EXISTS 在这种情况下通常比 LEFT JOIN 具有性能优势(例如,参见 this)。