Что такое список SELECT и подзапрос, который игнорируется в операторе EXISTS? - PullRequest
1 голос
/ 26 ноября 2011

Это цитата из http://dev.mysql.com/doc/refman/5.0/en/exists-and-not-exists-subqueries.html: "Если подзапрос вообще возвращает какие-либо строки, подзапрос EXISTS равен TRUE, а подзапрос NOT EXISTS равен FALSE. Например:

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

Традиционно,подзапрос EXISTS начинается с SELECT *, но может начинаться с SELECT 5 или SELECT column1 или чего-либо еще. MySQL игнорирует список SELECT в таком подзапросе, поэтому он не имеет значения. "

Что делает последнийдва предложения означают?Могу ли я привести пример того, почему это важно?Я понял, что независимо от того, что я использую в своем начальном SELECT, я получаю все столбцы в моих наборах результатов.Это то, о чем идет речь?

Ответы [ 5 ]

2 голосов
/ 26 ноября 2011

Последние два предложения в основном говорят о том, что, пока подзапрос возвращает что-то, что НЕ является пустой таблицей, то то, что вы помещаете в это выражение SELECT, является спорным, поскольку вы просто проверяете существование.Пример:

SELECT DISTINCT store_type FROM stores
  WHERE EXISTS (SELECT 'poop' FROM cities_stores
                WHERE cities_stores.store_type = stores.store_type);

Мы получим poop для каждой строки, которая возвращается во втором SELECT.Опять же, пока существует хотя бы одна строка в towns_stores, где store_type равен начальному SELECT's store_type, тогда эта таблица БУДЕТ существовать.

Важность?В этом примере, скажем, у нас много магазинов разных типов.Внезапно мы хотим знать все различные типы магазинов, которые у нас существуют, с несколькими оговорками: тип магазина - это тип, найденный в городе (представленными в городах сити), а также НЕ те, которые находятся в разработке,но те, которые на самом деле открыты (представлены нашей таблицей магазинов).Ну, мы бы использовали этот запрос, чтобы получить список всех типов store_types.

И причина, по которой вы получаете все столбцы, в том, что * означает все столбцы в таблице (таблицах), которые ВЫ ВЫБИРАЛИ ИЗ.

2 голосов
/ 26 ноября 2011

Эти предложения не о части SELECT column..., а ТОЛЬКО о части ... EXISTS (SELECT *....Два предложения говорят вам, что следующие утверждения эквивалентны:

SELECT column1 FROM t1 WHERE EXISTS (SELECT * FROM t2);
SELECT column1 FROM t1 WHERE EXISTS (SELECT 5 FROM t2);
SELECT column1 FROM t1 WHERE EXISTS (SELECT 42 FROM t2);
SELECT column1 FROM t1 WHERE EXISTS (SELECT random() FROM t2);
SELECT column1 FROM t1 WHERE EXISTS (SELECT column FROM t2);
SELECT column1 FROM t1 WHERE EXISTS (SELECT NULL FROM t2);
SELECT column1 FROM t1 WHERE EXISTS (SELECT 1/0 FROM t2);

Не больше, не меньше.

Поскольку возвращаемое отношение указано в первой части SELECT column1, вторая SELECT не влияет на возвращаемые строки.

1 голос
/ 26 ноября 2011

Это говорит о том, что если у вас есть следующее, выберите:

SELECT a1,b1,c1,...,z1 FROM t1 WHERE EXISTS (SELECT a2,b2,c3,...,z2 FROM t2)

Список столбцов a2, b2, c3, ..., z2 игнорируется, так как его значение не нужно для того, чтобы решить, существует строка или нет. Это экономит память и время вычислений.

редактировать: Чтобы прояснить ситуацию: EXISTS проверяет непустоту результата запроса. Поскольку не нужно знать, ЧТО было возвращено запросом, чтобы узнать, что он возвратил что-то или нет, столбцы выбора можно игнорировать.

1 голос
/ 26 ноября 2011

При использовании EXISTS вы проверяете только наличие строки, независимо от значений.Часть SELECT важна, если вы используете IN.

Таким образом, выбранные столбцы для EXISTS можно игнорировать, тогда как для подзапроса IN это важно.

0 голосов
/ 26 ноября 2011

Я думаю, что вы путаете некоррелированные подзапросы (каков ваш код), где подзапрос может оцениваться независимо"внешнего" запроса. «Независимо оцениваемые подзапросы» - подзапрос, который может быть оценен без контекста суперзапроса:

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

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

SELECT column1 
FROM t1 
WHERE EXISTS 
      ( SELECT * 
        FROM t2
        WHERE t2.somecolumn = t1.somecolumn
      )

и обычно может быть записано также как:

SELECT column1 
FROM t1 
WHERE somecolumn IN
      ( SELECT somecolumn
        FROM t2
      )
...