2017-01-04 3 views
1

Мне интересно, почему, когда вы присоединяете две таблицы к ключу внутри существующего подзапроса, соединение должно происходить в предложении WHERE вместо предложения FROM.Присоединиться к подзапросу «существует»

Это мой пример:

Регистрация в ЕКОМ:

SELECT payer_id 
    FROM Population1 
WHERE NOT EXISTS 
     (Select * 
      From Population2 join Population1 
      On Population2.payer_id = Population1.payer_id) 

Регистрация в ИНЕКЕ:

SELECT payer_id 
    FROM Population1 
    WHERE NOT EXISTS 
     (Select * 
      From Population2 
      WHERE Population2.payer_id = Population1.payer_id) 

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

Может кто-то просто объяснить мне, почему, когда соединение происходит в подзапросах EXISTS? Если вы берете подзапросы без родительского запроса и запускаете их, они буквально дают вам тот же результат.

Это очень помогло бы мне запомнить, чтобы не продолжать делать эту ошибку при использовании.

Заранее спасибо.

+1

первый запрос практически не имеет смысла. Итак, вы присоединяетесь к таблицам «Population1» с «Population2», и вы говорите, что если в результате этого соединения существует какая-либо строка, то ничего не возвращайте из «Population1». Вот почему вы получаете 0 строк – Lamak

+0

Покажите некоторые примеры данных из 2 таблиц и ожидаемый результат. Тогда мы можем вам помочь. – PhillipXT

+0

И второй запрос показывает вам все строки в '' 'Population1''', где нет соответствующей записи в' '' Population2'''. – Anand

ответ

5

Вам нужно понять различие между обычным подзапросом и коррелированным подзапросом.

Используя ваши примеры, это должно быть легко. Первый where оговорка:

where not exists (Select 1 
        from Population2 join 
         Population1 
         on Population2.payer_id = Population1.payer_id 
       ) 

Это условие делает точно что он говорит, что это делает. Подзапрос не имеет никакого отношения к внешнему запросу. Таким образом, not exists либо отфильтрует все строки, либо сохранит все строки.

В этом случае движок запускает подзапрос и определяет, что возвращается хотя бы одна строка. Следовательно, not exists возвращает false во всех случаях, и ничего не возвращается.

Во втором случае подзапрос представляет собой коррелированный подзапрос. Таким образом, для каждой строки в population1 подзапрос запускается с использованием значения Population1.payer_id. В некоторых случаях соответствующие строки существуют в Population2; они отфильтровываются. В других случаях совпадающие строки не существуют; они находятся в результирующем наборе.

+1

Спасибо! Я должен был это признать. Итак, чтобы подтвердить мое понимание, поскольку я включаю P1 в предложение FROM в первом запросе, я не ссылаюсь на один и тот же экземпляр таблицы из родительского запроса и поэтому никак не свяжусь с родительским запросом. Принимая во внимание, что, поскольку я использую P1 в предложении WHERE во втором запросе, это делает его коррелированным подзапросом, и он ссылается на таблицу P1 родительского запроса. Это верно? – Tyler

+1

@ Тайлер - это правильно. – Hogan

0

Первый пример фактически не относится к базовой таблице, которая создает непредсказуемую логику.

Другой способ сделать то же логика будет:

SELECT payer_id 
FROM Population1 P1 
LEFT JOIN Population2 P2 ON 
    P2.Payer_Id = P1.Payer_Id 
WHERE 
    P2.Payer_Id IS NULL 
+1

Логика предсказуема в первом запросе - просто не полезно. – Hogan

0

Вы QRY вернуть ROW EXISTS всегда, если существует, даже если есть один результат строки.

Select * 
from Population2 
join Population1 on Population2.payer_id = Population1.payer_id 

Если существует хотя бы одну строку из этого соединения (и наверняка существует), вы можете себе представить ваш subqry выглядит следующим образом:

select 'ROW EXISTS' 

И результат:

select * 
from Population1 
where not exists (select 'ROW EXISTS') 

Таким образом, ваш возврат против полуоси:

payer_id 1 -> некоторые ROW EXISTS -> не возвращать эту строку

payer_id 2 -> некоторые ROW EXISTS -> не возвращают эту строку

Смежные вопросы