如何通过JOIN从另一个表中查找不存在的数据?
我有两个表 TABLE1,看起来像:
id name address
1 mm 123
2 nn 143
和 TABLE2 w/c 看起来像:
name age
mm 6
oo 9
我想通过比较 TABLE1
与 TABLE2
来获取不存在的名称。
所以基本上,我必须得到第二行,w/c有一个TABLE2
中不存在的NN名称,输出应该如下所示:
id name address
2 nn 143
我已经尝试过这个,但它没有不起作用:
SELECt w.* FROM TABLE1 W INNER JOIN TABLE2 V
ON W.NAME <> V.NAME
它仍在获取现有记录。
I have two tables TABLE1 which looks like:
id name address
1 mm 123
2 nn 143
and TABLE2 w/c looks like:
name age
mm 6
oo 9
I want to get the non existing names by comparing the TABLE1
with the TABLE2
.
So basically, I have to get the 2nd row, w/c has a NN name that doesn't exist in the TABLE2
, the output should look like this:
id name address
2 nn 143
I've tried this but it doesn't work:
SELECt w.* FROM TABLE1 W INNER JOIN TABLE2 V
ON W.NAME <> V.NAME
and it's still getting the existing records.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
INNER JOIN
在这里没有帮助。解决此问题的一种方法是使用
LEFT JOIN
:An
INNER JOIN
doesn't help here.One way to solve this is by using a
LEFT JOIN
:您需要的关系运算符是半差异,又名 反连接。
大多数 SQL 产品缺乏显式的半差分运算符或关键字。标准 SQL-92 没有(它有一个
MATCH(子查询)
半连接谓词,但是,尽管很容易想到其他方式,但NOT MATCH(子查询)
的语义是与半差异不同;FWIW 真正的关系语言 教程 D 成功使用不匹配
半差异)。半差异当然可以使用其他 SQL 谓词来编写。最常见的是:在
WHERE
子句中测试空值的外连接,紧随其后的是EXISTS
或IN(子查询)
。使用EXCEPT
(相当于 Oracle 中的MINUS
)是另一种可能的方法,如果您的 SQL 产品支持的话,并且再次取决于数据(具体来说,当两个表的标题为相同)。就我个人而言,我更喜欢在 SQL 中使用 EXISTS 进行半差分联接,因为联接子句在书面代码中更接近,并且不会导致对联接表的投影,例如
与
NOT IN 一样(子查询)
(与外连接方法相同),如果子查询中的WHERE
子句涉及空值,则需要格外小心(提示:ifWHERE
子查询中的子句计算UNKNOWN 由于存在空值,因此将被EXISTS
强制为 FALSE,这可能会产生意外的结果)。更新(3年过去了):我已经转向更喜欢
NOT IN (subquery)
因为它更具可读性,如果您担心空值的意外结果(而且您应该担心),请停止使用完全是我多年前做过的。一种更具可读性的方法是不需要范围变量
W
和V
例如The relational operator you require is semi difference a.k.a. antijoin.
Most SQL products lacks an explicit semi difference operator or keyword. Standard SQL-92 doesn't have one (it has a
MATCH (subquery)
semijoin predicate but, although tempting to think otherwise, the semantics forNOT MATCH (subquery)
are not the same as for semi difference; FWIW the truly relational language Tutorial D successfully uses theNOT MATCHING
semi difference).Semi difference can of course be written using other SQL predicates. The most commonly seen are: outer join with a test for nulls in the
WHERE
clause, closely followed byEXISTS
orIN (subquery)
. UsingEXCEPT
(equivalent toMINUS
in Oracle) is another possible approach if your SQL product supports it and again depending on the data (specifically, when the headings of the two tables are the same).Personally, I prefer to use
EXISTS
in SQL for semi difference join because the join clauses are closer together in the written code and doesn't result in projection over the joined table e.g.As with
NOT IN (subquery)
(same for the outer join approach), you need to take extra care if theWHERE
clause within the subquery involves nulls (hint: ifWHERE
clause in the subquery evaluates UNKNOWN due to the presence of nulls then it will be coerced to be FALSE byEXISTS
, which may yield unexpected results).UPDATE (3 years on): I've since flipped to preferring
NOT IN (subquery)
because it is more readable and if you are worried about unexpected results with nulls (and you should be) then stop using them entirely, I did many more years ago.One way in which it is more readable is there is no requirement for the range variables
W
andV
e.g.