2012-02-03 85 views
24

使用IMDB數據庫中的凱文·貝肯數,我有表actorcastsmovie,我需要具有2的凱文·貝肯數我想這應該這樣做來選擇演員,但我得到0行返回。我的錯誤是什麼?SQL查詢來尋找的2

select fname, lname 
from actor join casts on pid=actor.id 
where actor.id in (
    select a3.id --actors who have a kb number of 2 
    from casts c3 join actor a3 on c3.pid=a3.id, 
    (
    (select c1.mid --actors who have a kb number of 1 
    from (casts c1 join actor a1 on c1.pid=a1.id), (casts c2 join actor a2 on c2.pid=a2.id) 
    where c1.mid=c2.mid and a2.fname='Kevin' and a2.lname='Bacon') 
    )Level1 where c3.mid=Level1.mid 
) 
and actor.id not in (select a4.id --and only a kb number of 2 
    from (casts c4 join actor a4 on c4.pid=a4.id), (casts c5 join actor a5 on c5.pid=a5.id) 
    where c4.mid=c5.mid and a5.fname='Kevin' and a5.lname='Bacon'); 

下面是表模式:

ACTOR (id, fname, lname, gender) 
MOVIE (id, name, year) 
CASTS (pid, mid, role) 

mid是一個外鍵的影片ID和pid是一個外鍵角色標識。

請注意,限制這個問題禁止我使用臨時表或遞歸:查詢應該使用子查詢。


我也試過

select count(distinct pid) from casts join actor on pid=actor.id where mid in (
    select mid from casts where pid in (
     select distinct pid from casts where mid in (
      select mid from casts join actor on pid=actor.id where fname='Kevin' and lname='Bacon'))) 

and pid not in 
    (select distinct pid from casts where mid in (
     select mid from casts join actor on pid=actor.id where fname='Kevin' and lname='Bacon')); 

這也似乎像它應該工作,但它沒有完成。


我終於設法得到一些工作代碼:

select count(distinct pid) from casts where mid in (
    select mid from casts where pid in (
     select distinct pid from casts where mid in (
      select mid from casts join actor on pid=actor.id where fname='Kevin' and lname='Bacon'))) 

and pid not in 
    (select distinct pid from casts where mid in (
     select mid from casts join actor on pid=actor.id where fname='Kevin' and lname='Bacon')); 

子查詢返回明智的答案,至少。但它是永恆的。每個子查詢都花了30秒鐘,但他們一起花6分鐘計數。爲什麼?


注意:這是給我作爲家庭作業。爲了避免我的學術不端行爲的一致性,我寧願如果人們沒有發佈完整的/確切的解決方案,而是指出我做錯的一般事情/就如何去做這件事情提出一般性建議。

+2

@AbeMiessler http://sqlfiddle.com/ – scottm 2012-02-03 22:57:02

+0

使測試用例:創建數據 – cetver 2012-02-03 23:04:16

+0

噢臨時表,在這裏,我只是想出瞭如何使用遞歸CTE做到這一點(這是有趣的處理週期圖的環境)...爲什麼你不允許使用它們?雖然,不是一些新的非SQL數據庫應該在這類事情上做得更好 - 我雖然有人制作了網絡圖數據庫?你被允許使用CTE嗎? – 2012-02-03 23:52:34

回答

9

爲了給出一個解決方案的草圖,而不是我會用這種一般方法

SELECT * 
FROM ACTOR 
WHERE id IN (
SELECT id 
     /* ... of actors that have worked on a film worked 
     on by actors that have worked on a KB film*/ 
EXCEPT 
SELECT id 
/* ... of all actors that have worked on a KB film 
     including KB himself*/) 

而且因爲你是不允許使用遞歸的CTE反正這裏是使用這些答案的精確解。

WITH RecursiveCTE 
    AS (SELECT C.pid, 
       C.mid, 
       0 as Level 
     FROM CASTS C 
       JOIN ACTOR A 
        ON A.id = C.pid 
     WHERE A.fname = 'Kevin' 
       and A.lname = 'Bacon' 
     UNION ALL 
     SELECT c1.pid, 
       c2.mid, 
       R.Level + 1 
     FROM RecursiveCTE R 
       JOIN CASTS c1 
        ON c1.mid = R.mid 
        AND R.Level < 2 
       JOIN CASTS c2 
        ON c1.pid = c2.pid) 
SELECT * 
FROM ACTOR 
WHERE id IN (SELECT pid 
       FROM RecursiveCTE 
       GROUP BY pid 
       HAVING MIN(Level) = 2) 
+0

尋找更多的一般想法重新:我做錯了/我應該做什麼,但我會運行您的查詢和投票你,如果答案匹配回答我(希望最終)得到。 – Colleen 2012-02-04 00:13:50

+0

嗯,這仍然是一個實際的答案,我認爲他想避免。 – ErikE 2012-02-04 00:13:53

+0

這是一個實際的答案,但是我在發佈答案後發佈了評論,所以沒關係。 – Colleen 2012-02-04 00:15:50