如何摆脱NOT EXISTS

时间:2012-03-09 15:37:57

标签: sql join left-join inner-join not-exists

我有一个不是很复杂但很混乱的sql我觉得我有一个等价或重合计数是相同的。

SQL1:

SELECT a, b
FROM table1
WHERE NOT EXISTS(
  SELECT a, c
  FROM TABLE2
  WHERE table2.a != table1.a)

SQL2

SELECT table1.a, table1.b
FROM table1
LEFT JOIN table2 ON table2.a = table1.a
WHERE table2.a IS NULL

两者的计数相同,但不确定这是否是偶然的,我想确保转换不会改变原始功能。

4 个答案:

答案 0 :(得分:3)

看起来不一样 - 但它很接近。您的LEFT JOIN语法与:

相同
SELECT a, b
FROM table1
WHERE NOT EXIST(
  SELECT a, c
  FROM TABLE2
  WHERE table2.a = table1.a)

注意“=”而不是“!=”。你确定那不是你的吗?

您的实际查询会转换为“不存在不匹配行的位置”,这可能很奇怪,但可以通过更改JOIN条件来表达:

SELECT a, b
FROM table1
LEFT JOIN table2 ON table2.a != table1.a
WHERE table2.a IS NULL

答案 1 :(得分:2)

第一个查询,就像你拥有它一样,返回TABLE1的所有行,其中a匹配TABLE2中a的所有值。因此,它将返回零行,除非TABLE2中有a的单个非空值,并且该值存在于TABLE1中。在这种情况下,它将返回与TABLE1中具有该值a一样多的行。

第二个查询完全不同。它将返回TABLE1的所有行,其中TABLE2中不存在a

所以它是“ 匹配所有 ”(查询1)与“ 不匹配任何 ”(查询2)。您获得相同行数的事实纯属巧合。

如果您在第一个!=中更改了=,那么您的查询将是相同的,如下所示:

SELECT a, b
FROM table1
WHERE NOT EXISTS(
  SELECT a, c
  FROM TABLE2
  WHERE table2.a = table1.a)

这会得到table1中a的值,而table2中不存在这些值。这完全相同:

SELECT table1.a, b
FROM table1
LEFT JOIN table2 ON table2.a = table1.a
WHERE table2.a IS NULL

尽管如此,它们并不等同。您必须在第一个!=中更改=才能生成{{1}}。

答案 2 :(得分:2)

对于第一个查询,即

SELECT a, b
FROM table1
WHERE NOT EXISTS(
  SELECT a, c
  FROM TABLE2
  WHERE table2.a != table1.a)

如果atable1的所有值都是相同的值,并且table2中的所有行都与table1中的所有行相同,则会返回所有行}或table2是空集。否则,结果将是空集。

同样不能与第二次查询相同。

答案 3 :(得分:1)

SELECT a, b, c , d
FROM table1 t1
WHERE NOT EXISTS( SELECT * FROM table2 nx
  WHERE nx.y = t1.a
  )
  ;

这个(“相关子查询”)方法有一个很大的优点:表table2从外部查询中看不到,并且不会污染它,或者混淆你的想法。子查询只生成一点信息:它是存在还是不存在。 是或不是......
在这方面,LEFT JOIN习惯用法很糟糕,因为你必须检查外部查询中的xxx IS NULL条件 ,而xxx从内部查询引用table2。

从技术上讲,没有区别。