Как избавиться от НЕ СУЩЕСТВУЮЩЕГО - PullRequest
1 голос
/ 09 марта 2012

У меня есть sql, который не очень сложен, но достаточно запутан, что я задаю вопрос, скорее, у меня есть эквивалент или совпадение, что количество одинаковое.SQL2

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

Счет на обоих одинаков, но я не уверен, что это случайно, и я хочу убедиться, что преобразование не изменит исходную функциональность.

Ответы [ 4 ]

3 голосов
/ 09 марта 2012

Это не выглядит одинаково - но это близко. Ваш синтаксис 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
2 голосов
/ 09 марта 2012

Для первого запроса, т. Е.

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

. Это вернет все строки, когда все значения a в table1 являются одним и тем же значением, и либо все строки в table2 являютсято же значение, что и table1 или table2, является пустым набором.В противном случае результатом будет пустой набор.

То же самое не может быть таким же, как ваш второй запрос.

2 голосов
/ 09 марта 2012

Первый запрос, как он есть, возвращает все строки таблицы TABLE1, где a соответствует всем значениям a в таблице TABLE2. Следовательно, он вернет ноль строк, , если только в TABLE2 нет единственного ненулевого значения для a, и это значение существует в TABLE1. В этом случае он вернет столько строк, сколько имеется в TABLE1 с этим значением a.

Второй запрос совершенно другой. Он просто вернет все строки таблицы TABLE1, где a не существует в таблице TABLE2.

То есть « соответствует всем » (запрос 1) против « не соответствует ни одному » (запрос 2). Тот факт, что вы получаете одинаковое количество строк, является чистым совпадением.

Ваши запросы будут эквивалентны, если вы изменили != на = в первом, например:

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

Получает значения a в таблице1, которых нет в таблице2. Это точно так же, как:

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

Как вы понимаете, они НЕ эквивалентны. Вы должны изменить != на = в первом, чтобы сделать их такими.

1 голос
/ 09 марта 2012
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 из внутреннего запроса.

Технически, нет никакой разницы.

...