Интерпретация оператора SQL EXISTS в подзапросе?

Я прохожу онлайн-курс по базе данных. Теперь я понимаю следующий запрос

SELECT column1 FROM t1 WHERE EXISTS (SELECT * FROM t2);

что-то вроде

SELECT column1 FROM t1 WHERE TRUE;

но, подойдя к подзапросу с EXISTS, я впадаю в замешательство.

(Колледж имеет ключ (имя, штат).) Следующий запрос ищет названия колледжей, в которых есть другие колледжи в том же штате.

SELECT name,state 
FROM College C1
WHERE EXISTS (SELECT * FROM College C2 
              WHERE C1.state = C2.state and C1.name != C2.name);

Подзапрос вернет отношение, верно? так как оно находится внутри круглых скобок, оно вычисляется первым.

И возвращаемое отношение действительно существует из-за моей таблицы, созданной на основе артефактов. Таким образом, оператор EXISTS всегда возвращает TRUE, результатом является полная таблица с выбранными столбцами.

Правки: извините за не очень хорошую демонстрацию. вот мое отношение

Standford CA
Berkley CA
MIT MA

истинный результат

Standford CA
Berkley CA

но я думаю, что это должно быть

Standford CA
Berkley CA
MIT MA

Видимо ошибка в моих рассуждениях. Подскажите, где это и что нужно исправить?


person WeiChing 林煒清    schedule 22.11.2013    source источник
comment
Это выглядит хорошо для меня. Я полагаю, вы убедились, что в том же штате есть колледжи, в которых нет других колледжей?   -  person Justin Pihony    schedule 22.11.2013
comment
Вы выполняете коррелированный подзапрос, объединяя C1 и C2, что означает, что существующий запрос выполняется один раз для каждой строки C1.   -  person tawman    schedule 22.11.2013
comment
sqlfiddle.com/#!2/385119/1 доказывает, что это должно работать как есть   -  person Justin Pihony    schedule 22.11.2013
comment
отредактировано для добавления демонстрационного отношения и результата,   -  person WeiChing 林煒清    schedule 22.11.2013


Ответы (4)


Я не думаю, что в этом случае нет необходимости в коррелированном подзапросе или чем-то подобном. Вы можете просто поступить из колледжа в колледж, где штаты одинаковы, а колледжи разные:

SELECT c1.name,c1.state 
FROM College C1,
College C2 
WHERE C1.state = C2.state and C1.name != C2.name

скрипт SQL

Если вы хотите немного почитать о коррелированных подзапросах, вот хороший ресурс:

Clicky!

person Andrew    schedule 22.11.2013

Я не уверен, почему вы думаете, что должны получить все строки, но я попытаюсь объяснить EXISTS немного лучше, так как вы, кажется, думаете, что все, что он делает, это возвращает true?

EXISTS выполняет свой запрос и возвращает true, если возвращаются ЛЮБЫЕ строки, и false, если возвращается 0 строк*. В вашем случае ваш запрос запрашивает все колледжи, в которых есть более одной школы в штате. Вот почему он исключает MIT (у него только 1 школа). Причина, по которой я резюмирую ваш запрос, чтобы означать вышеизложенное, заключается в том, что вы берете каждую строку и делаете перекрестные ссылки на одну и ту же таблицу, за исключением того, что на этот раз вы включаете школы с одним и тем же состоянием, а затем исключаете текущую проверяемую школу.

* На самом деле оператор select является артефактом SQL и даже не выполняется. Часто вы будете видеть, как люди делают SELECT 1.

person Justin Pihony    schedule 22.11.2013
comment
спасибо, я, вероятно, нашел решение своего вопроса в ссылке, которую предоставил Андрей, поэтому я приписал ответ ему. Сначала я думал, что подзапрос является независимым и одноразовым запросом (точно так же, как оператор IN получает отношение из одноразового независимого запроса). Но по ресурсам ссылки практически коррелированный подзапрос не похож на одноразовый запрос, он больше похож на проверку того, существует ли условие построчно. - person WeiChing 林煒清; 23.11.2013

SELECT name,state 
FROM College C1
WHERE EXISTS (SELECT * FROM College C2 
              WHERE C1.state = C2.state and C1.name != C2.name);

На английском примерно

Выберите имя столбца и штат из таблицы колледжей, где есть колледж, который находится в том же штате, но имеет другое имя.

Так что результат имеет смысл.

person T I    schedule 22.11.2013

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

select name, state, records -1 others
from college c1
join (select state st, count(*) records
from college
group by state
having count(*) > 1) temp on state = st
person Dan Bracuk    schedule 22.11.2013