Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Волженные подзапросы. Работа EXISTS, NOT EXISTS. / 12 сообщений из 12, страница 1 из 1
03.03.2015, 13:46:25
    #38893503
unnomen
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Волженные подзапросы. Работа EXISTS, NOT EXISTS.
Люди, объясните пожалуйста работу запроса:
Код: sql
1.
SELECT * FROM Customers WHERE NOT EXISTS (SELECT * FROM Products WHERE NOT EXISTS (SELECT * FROM Orders WHERE product_id = Products.id AND customer_id = Customers.id));


Customers - клиенты
Products - товары
Orders - заказы
Не могу понять логику выполнения этого запроса.

Единственно, что я понял - это запросы такого вида:
Код: sql
1.
SELECT * FROM Products WHERE EXISTS (SELECT * FROM Orders WHERE product_id = Products.id AND customer_id IS NOT NULL);


Вывод списка товаров, которые были заказаны хоть одним клиентом.
Код: sql
1.
SELECT * FROM Products WHERE NOT EXISTS (SELECT * FROM Orders WHERE product_id = Products.id AND customer_id IS NOT NULL);


Вывод списка товаров, которые не были заказаны ни одним клиентом.

Если можно, объясните кто нибудь пожалуйста пошаговое выполнение запроса, буду очень признателен.
...
Рейтинг: 0 / 0
03.03.2015, 13:55:17
    #38893516
Волженные подзапросы. Работа EXISTS, NOT EXISTS.
unnomen,

что именно не понятно-то?
...
Рейтинг: 0 / 0
03.03.2015, 13:57:02
    #38893522
unnomen
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Волженные подзапросы. Работа EXISTS, NOT EXISTS.
Добрый Э - Эх,

Логика выполнения этого запроса.
В литературе написано, что это "Вывод списка клиентов, заказавших все виды товаров".
Я не могу понять, как логически выполняется этот запрос.
...
Рейтинг: 0 / 0
03.03.2015, 14:30:16
    #38893587
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Волженные подзапросы. Работа EXISTS, NOT EXISTS.
Допустим, обрабатывается некая запись таблицы Customers.
Допустим, для неё обрабатывается некая запись таблицы Products.
Внутренний подзапрос выберет все строки для этой пары из таблицы Orders.
Средний подзапрос соответственно вернёт все строки, НЕ присутствующие во внутренней выборке. Т.е. список записей из Products, для которых данный Customers ничего не заказал.
Внешний запрос соответственно вернёт только те строки, для которых этот список (незаказанных продуктов) пуст.
...
Рейтинг: 0 / 0
03.03.2015, 14:53:16
    #38893610
unnomen
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Волженные подзапросы. Работа EXISTS, NOT EXISTS.
Akina,

Вроде бы понял, но не совсем.

Получается так:

Есть три клиента:
Код: sql
1.
2.
3.
Иванов
Петров
Сидоров


Есть пять товаров:
Код: sql
1.
2.
3.
4.
5.
Ножницы
Ручка
Карандаш
Ластик
Краски


В заказах имеются записи:
Код: sql
1.
2.
3.
"Иванов" заказал "Ножницы"
"Петров" заказал "Ластик"
"Иванов" заказал "Ножницы"



К примеру, Иванов два раза заказывал Ножницы, Сидиров вообще ничего не заказывал.
При запросе:
Код: sql
1.
SELECT * FROM Products WHERE NOT EXISTS (SELECT * FROM Orders WHERE product_id = Products.id AND customer_id IS NOT NULL);


вернёт ответ:
Код: sql
1.
2.
3.
"Ручка"
"Карандаш"
"Краски"



При запросе:
Код: sql
1.
SELECT * FROM Customers WHERE NOT EXISTS (SELECT * FROM Products WHERE NOT EXISTS (SELECT * FROM Orders WHERE product_id = Products.id AND customer_id = Customers.id));


происходит проверка, имеется ли список:
Код: sql
1.
2.
3.
"Ручка"
"Карандаш"
"Краски"


для "Иванов", "Петров", "Сидоров" пустым? Если да, то выводится этот клиент, нет - получается возвращается false;

В этом примере следует, что значение вернёт false (вернёт пустую таблицу), т.к. этот список существует для "Иванов", "Петров", "Сидоров".

Правильно?
...
Рейтинг: 0 / 0
03.03.2015, 14:55:51
    #38893613
unnomen
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Волженные подзапросы. Работа EXISTS, NOT EXISTS.
Akina,

Но! Соответственно, для "Иванов" список будет:
Код: sql
1.
2.
3.
4.
Ручка
Карандаш
Ластик
Краски


Для "Петров" список будет:
Код: sql
1.
2.
3.
4.
Ножницы
Ручка
Карандаш
Краски


Для "Сидоров" список будет:
Код: sql
1.
2.
3.
4.
5.
Ножницы
Ручка
Карандаш
Ластик
Краски



Верно?
...
Рейтинг: 0 / 0
03.03.2015, 15:38:12
    #38893682
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Волженные подзапросы. Работа EXISTS, NOT EXISTS.
Похоже на правду.
...
Рейтинг: 0 / 0
03.03.2015, 15:43:23
    #38893692
unnomen
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Волженные подзапросы. Работа EXISTS, NOT EXISTS.
Akina,

Спасибо большое. Теперь всё понятно!:)
...
Рейтинг: 0 / 0
04.03.2015, 07:48:30
    #38894199
Arhat109
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Волженные подзапросы. Работа EXISTS, NOT EXISTS.
unnomen,

Во втором примере - 2 вложенных "несуществования"... по русски оно читается примерно так:

Отдай мне всех кастамеров, для которых НЕ существует продуктов с отсутствующими покупками этим же кастамером.

То есть, второй вложенный подзапрос ограничивает не существование факта покупки для некоего товара из первого подзапроса. И верно, да. Для каждого покупателя первый подзапрос сформирует такие списки товаров "без" их покупок...

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

Ну и так, замечание: в подзапросах на (не)существование - вовсе не требуется делать "select * ". Вполне достаточно "SELECT 1 "... ибо выборка найденного подзапросом - никуда не уперлась. А вот, ежели вы её "запросили", то Мускуль таки будет её формировать... по сути зазря.
...
Рейтинг: 0 / 0
04.03.2015, 08:24:29
    #38894221
Волженные подзапросы. Работа EXISTS, NOT EXISTS.
Arhat109Ну и так, замечание: в подзапросах на (не)существование - вовсе не требуется делать "select * ". Вполне достаточно "SELECT 1 "... ибо выборка найденного подзапросом - никуда не уперлась. А вот, ежели вы её "запросили", то Мускуль таки будет её формировать... по сути зазря.ну, так-то неправда твоя... сервер при выполнении запроса банально игногрирует select-лист [not]exists-подзапроса. поэтому там можно написать любую конструкцию, которая пройдет синтаксический разбор.
как пример, там можно написать хоть деление строки на ноль. :) В качестве доказательства своих слов: ссылка
если бы сервер выполнял select-лист [not]exists-подзапроса, то сей запрос упал бы как минимум с ошибкой деления на ноль. я уж не говорю о невозможности преобразования строки 'bla-bla-bla' в число.
...
Рейтинг: 0 / 0
04.03.2015, 08:26:50
    #38894222
Волженные подзапросы. Работа EXISTS, NOT EXISTS.
Добрый Э - Эх,

з.ы.
если вдруг sqlfiddle.com не будет фурычить, то завсегда можно повторить эксперимент на любой доступной базе:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
create table b$m_test (num int);
insert into b$m_test values(0);
insert into b$m_test values(1);


select * 
  from b$m_test t0 
 where not exists 
        (
          select 'bla-bla-bla'/0
            from b$m_test t1
           where t1.num > t0.num
        )
...
Рейтинг: 0 / 0
04.03.2015, 09:53:40
    #38894274
Arhat109
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Волженные подзапросы. Работа EXISTS, NOT EXISTS.
Добрый Э - Эх,

Возможно уже и игнорит... не далее года назад, у меня была подобная фишка с несуществованием. Замена селекта на 1 - ускоряло запрос просто в разы.
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Волженные подзапросы. Работа EXISTS, NOT EXISTS. / 12 сообщений из 12, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]