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

时间:2015-03-30 14:14:13

标签: sql sql-server tsql join criteria

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

我有两个表,一个源表我正在尝试从中选择数据,一个包含序列#和事务#的引用表(源表也有这些列,等等)。我想做两个不同的SELECT,一个是源表中存在串行/反转编号对,另一个是串行/反转编号不存在的SELECT。 (串行号和反向号的组合是这两个表的主键)

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

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

我认为这应该给我来自源表的所有内容,它具有与引用表中的一个匹配的串/反对。我不肯定这是正确的,但它返回了合理数量的结果,我认为它看起来不错。

当我去做相反的事情时,从序列/反式对不匹配的源到参考中的一个,我遇到问题。我尝试了以下查询:

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

当我运行此查询时,查询将继续进行,它开始返回的结果多于应有的结果,而不是实际在整个源表中。它最终以OOM异常结束,我让它运行20分钟+。对于一些persepctive我正在处理的源表有大约1300万条记录,参考表大约有105,000条。

那么我如何得到我正在寻找的结果呢?如果尚未清楚,则第一个查询的结果数+第二个查询的结果应该等于源表中的记录总数。

感谢您的帮助!

2 个答案:

答案 0 :(得分:5)

我认为你需要像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)。

答案 1 :(得分:4)

“LEFT JOIN”匹配一起匹配的记录,并为那些不适合的记录返回NULL。

因此,非匹配记录在来自引用表的列中都是NULL。这样,您可以添加一个where子句,只返回表“reference”的非可空列中的具有空值的记录(如primarykey)。

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