Я знаю, что есть очень похожие вопросы по этой теме. Дело в том, что каждый пример, который я видел, указывает на то, что EXISTS и IN являются одинаковыми и возвращают те же результаты. У меня есть пример использования обоих, но у меня разные результаты. Возможно, я делаю это неправильно. Я новичок в SQl в целом. Вот мои примеры кода с использованием MySQL.
Первый запрос с использованием IN
select lastname, firstname
from employees
where officecode in (select officecode from offices where country = 'USA');
Результат:
Второй запрос с использованием EXISTS:
select lastname, firstname
from employees
where exists (select officecode from offices where country = 'USA');
Результат:
Очевидно, что запросы не эквивалентны, так как я получаю разные результаты. Я использую IN и EXISTS неправильно?
Ваши два вопроса очень разные. Первый запрос:
select e.lastname, e.firstname
from employees e
where e.officecode in (select o.officecode from offices o where o.country = 'USA');
(Обратите внимание, что я определил все имена столбцов.)
Это получает сотрудников, где соответствующий офис находится в США.
Этот вопрос совсем другой:
select e.lastname, e.firstname
from employees e
where exists (select o.officecode from offices o where o.country = 'USA');
Это запрос "все или ничего". Он возвращает всех сотрудников, если какой-либо офис находится в США. Он ничего не возвращает.
Чтобы быть эквивалентным первому запросу, вам понадобится условие корреляции. Это связывает внутренний запрос с внешним запросом:
select e.lastname, e.firstname
from employees e
where exists (select 1
from offices o
where o.officecode = e.officecode and o.country = 'USA'
);
При этом изменении эти два запроса должны давать одинаковые результаты.
Чтобы они возвращали те же результаты, вам нужно предложение where для вашего оператора существования, чтобы связать его с вашим внешним запросом... from employees e where exists (select o.officecode from offices o where o.country = 'USA' and o.officecode = e.officecode)
. Возвращение каждого тоже другое. EXISTS
возвращает BOOLEAN
.
Exists
проверяет правильность условия.
Таким образом, во втором запросе будет выполняться первая часть запроса, когда в внутреннем запросе exists
условие true. Exists будет проверять, возвращает ли внутренний запрос одну или несколько строк. В вашем случае это будет правдой, и поэтому внешний запрос будет похож на select lastname, firstname from employees;
Но в первом случае он будет проверять условие, в котором все officecode
находятся в подзапросе, и соответствует officecode
во внешнем запросе и будет возвращать те, у которых есть страна USA
Левое соединение и нуль проверяются быстрее.
Select * from t1
Left join t2 on(t1.=t2)
Where t2.id is null