Что означает двойное предложение не существует?

SELECT c.name
FROM   Customer c
WHERE  NOT EXISTS(SELECT w.WID
                  FROM   Woker w
                  WHERE  NOT EXISTS(SELECT la
                                    FROM   look_after la
                                    WHERE  la.CID = c.CID
                                           AND la.WID = w.WID)); 

Я не знаю, что означает код ... Может ли кто-нибудь в общих чертах сказать мне, что делает код? C - это Клиент, о котором будет заботиться Рабочий.


person Halso Johnson    schedule 30.06.2013    source источник
comment
В каком смысле это не по теме? Это специфическая проблема программирования, с которой обычно сталкиваются при анализе базы данных, созданной экспертами по SQL.   -  person Andomar    schedule 30.06.2013
comment
Это идеально подходит для SO; это о программировании SQL, но о программировании и, следовательно, по теме.   -  person Jonathan Leffler    schedule 30.06.2013
comment
@Andomar Причина, по которой выбрана «не по теме», заключается в демонстрации минимального понимания решаемой проблемы; Есть и другие причины, не относящиеся к теме, которые не совсем похожи на предыдущие. Тем не менее, я не знаю, применима ли конкретная причина закрытия, и я открываю ее снова.   -  person Andrew Barber    schedule 30.06.2013
comment
@JonathanLeffler См. Мой комментарий к Andomar выше.   -  person Andrew Barber    schedule 30.06.2013


Ответы (2)


Запрос выбирает клиентов, о которых заботятся все сотрудники.

Двойной not exists - это способ реализовать реляционное подразделение.

person Andomar    schedule 30.06.2013
comment
Должно быть без: , о которых заботятся все сотрудники - person ypercubeᵀᴹ; 30.06.2013
comment
@ypercube: там, где нет работника, который бы не заботился о клиенте. Так что я думаю, что текущая версия в порядке. А вот двойное отрицание очень трудно прочесть. - person Andomar; 30.06.2013
comment
Запрос показывает клиентов, о которых заботятся все без исключения работники. - person ypercubeᵀᴹ; 30.06.2013
comment
@ypercube: Похоже, ты прав. Слишком сложно читать, чтобы использовать в продакшене без комментариев :) - person Andomar; 30.06.2013

В качестве иллюстрации к отличному ответу Андомара пример:

    -- Some test data
DROP SCHEMA tmp CASCADE;
CREATE SCHEMA tmp ;
SET search_path=tmp;

CREATE TABLE persons
        ( person_id  INTEGER NOT NULL PRIMARY KEY
        , pname   varchar
        );
INSERT INTO persons( person_id, pname ) VALUES
 (1 , 'Bob' ) ,(2 , 'Alice' ) ,(3 , 'Carol' )
        ;

CREATE TABLE movies
        ( movie_id  INTEGER NOT NULL PRIMARY KEY
        , mname   varchar
        );
INSERT INTO movies( movie_id, mname ) VALUES
 (1, 'The Blues brothers' ), (2, 'Modern Times' ), (3, 'The Sound of Music' )
,(4, 'Amadeus' ), (5, 'Never say Never' )
        ;

        -- people that have seen a particular movie
CREATE TABLE person_movie
        ( person_id  INTEGER NOT NULL
        , movie_id INTEGER NOT NULL
        , PRIMARY KEY ( person_id, movie_id)
        );
INSERT INTO person_movie( person_id, movie_id) VALUES
 (1 ,5 ) ,(1 ,1 )
,(2 ,5 ) ,(2 ,4 ) ,(2 ,1 ) ,(2 ,3 ) ,(2 ,2 )
,(3 ,1 ) ,(3 ,3 )
        ;

        -- Find the people that have seen ALL the movies
        -- This is equivalent to:
        -- Find persons for whom NO movie exists that (s)he has NOT seen
SELECT * FROM persons p
WHERE NOT EXISTS (
        SELECT * FROM movies m
        WHERE NOT EXISTS (
                SELECT * FROM person_movie pm
                WHERE pm.movie_id = m.movie_id
                AND pm.person_id = p.person_id
                )
        );

        -- similar: Find the movies that have been seen by ALL people
SELECT * FROM movies m
WHERE NOT EXISTS (
        SELECT * FROM persons p
        WHERE NOT EXISTS (
                SELECT * FROM person_movie pm
                WHERE pm.movie_id = m.movie_id
                AND pm.person_id = p.person_id
                )
        );                                             

Полученные результаты:

 person_id | pname 
-----------+-------
         2 | Alice
(1 row)

 movie_id |       mname        
----------+--------------------
        1 | The Blues brothers
(1 row)
person wildplasser    schedule 30.06.2013