2013-06-30 42 views
4
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是一名顧客,他將從一名工人那裏照顧。雙重不存在子句是什麼意思?

+1

在何種意義上,這是題外話?這是一個「特定的編程問題」,並且在分析由SQL專家設置的數據庫時經常遇到。 – Andomar

+0

對於SO而言,這是完美的主題;這是關於SQL編程,但編程,因此關於主題。 –

+0

@Andomar所選擇的「無主題」理由是爲了展示對解決問題的最小理解;還有更多脫離主題的原因與之前的不一樣。也就是說,我不知道具體的關閉原因是否適用,我正在重新打開它。 –

回答

8

該查詢選擇由所有工作人員檢查的客戶。

not exists是一種實現relational division的方法。

+1

應該沒有「不」:*「所有工作人員都會照看」* –

+1

@ypercube:沒有工人存在的人不照顧顧客。所以我認爲目前的版本是確定的。雖然很難閱讀雙重否定。 – Andomar

+0

該查詢顯示所有工作人員都會查看的客戶,無一例外。 –

2

作爲一個例子來Andomar的出色答卷一個例子:

-- 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)