1

我有一个不是很复杂但足够混乱的 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

4 回答 4

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
于 2012-03-09T15:46:16.120 回答
2

如您所见,第一个查询返回与TABLE2a中的所有值匹配的 TABLE1 的所有行。a因此,它将返回零行,除非TABLE2 中有一个非空值a,并且该值存在于 TABLE1 中。在这种情况下,它将返回与 TABLE1 中值为 的行一样多的行a

第二个查询完全不同。它只会返回aTABLE2 中不存在的所有 TABLE1 行。

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

如果您在第一个中更改!=了 for ,您的查询将是等效的,如下所示:=

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

这会为您提供atable1 中不存在于 table2 中的值。这与以下内容完全相同:

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

正如你所拥有的,它们并不等同。您必须在第一个中更改!=for才能使它们如此。=

于 2012-03-09T15:46:41.893 回答
2

对于第一个查询,即

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

a当in的所有值table1都是相同的一个值并且 in 的所有行table2与一个值相同table1或者table2是空集时,这将返回所有行。否则,结果将是空集。

您的第二个查询不能相同。

于 2012-03-09T16:29:45.533 回答
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。

从技术上讲,没有区别。

于 2012-03-09T16:26:13.717 回答