Существует в PostgreSQL не ясно - PullRequest
0 голосов
/ 13 апреля 2020

Мне трудно понять, что именно EXISTS делает в следующем запросе,

select basket_a.* from basket_a where exists (select from basket_b where basket_b.fruit <> basket_a.fruit);

Почему результат вышеприведенного запроса целиком равен basket_a? basket_a содержит

Apple
Orange
Banana
Cucumber

и basket_b содержит

Orange
Apple
Watermelon
Pear

Сложность проистекает из моей половины понимания аналога запроса

select basket_a.* from basket_a where exists (select from basket_b where basket_b.fruit = basket_a.fruit);

Вывод:

Apple Orange

Я предполагаю, что подзапрос оценивается, чтобы определить, возвращает ли он какие-либо строки. Так, basket_b.fruit = basket_a.fruit возвращает две строки

Apple Orange

, что превышает как минимум на одну строку . Таким образом, там, где существует , оценивается как true для этих двух строк и, поскольку он оценивается как false для двух других строк, которые не совпадают. Таким образом, соответствующие строки из корзины_a выбраны. Правильно ли я здесь с точки зрения моего понимания? Если это так, basket_b.fruit <> basket_a.fruit возвращает

Арбузная груша

И снова подзапрос возвращает две строки. К сожалению, Арбуз и Груша отсутствуют в basket_a, означает ли это, что результат where EXISTS равен false и select * from basket_a должен возвращать все строки? Вот как EXISTS должен себя вести?

Ответы [ 2 ]

2 голосов
/ 13 апреля 2020

Обратите внимание, что:

select basket_a.* from basket_a where not exists (select from basket_b where basket_b.fruit = basket_a.fruit);

не совпадает с:

select basket_a.* from basket_a where exists (select from basket_b where basket_b.fruit <> basket_a.fruit);

Последнее приводит к каждой строке, потому что в basket_b есть строка, то есть не равно текущей строке в basket_a. То, что вы ищете, это первый запрос.

1 голос
/ 14 апреля 2020

Проблема в том, что вы неправильно понимаете, что делает EXISTS. Он никогда не возвращает значение столбца, он всегда возвращает одно значение BOOLEAN. И это логическое значение определяется условием where в дополнительном выборе. Момент, который является истинной обработкой суб-выбора, заканчивается и возвращает истину. Повторяется при необходимости для каждой строки во внешнем запросе.

  pseudo code  
    for each element in ba
        for each element in bb
            if ba.element OPER bb.element 
               return true               
        end for
    end for 
    return false
  end pseudo code

Для реальных примеров см. fiddle . Особо обратите внимание на третий запрос, который фактически проверяет EXISTS, где элементы различаются для одного и того же набора, а НЕ для набора с одинаковыми значениями, но фактически с одним и тем же набором.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...