2012-02-03 10 views
24

IMDB डेटाबेस का उपयोग के केविन बेकन संख्या देखने के लिए, मैं टेबल actor, casts है, और movie, और मैं 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 एक फिल्म आईडी के लिए एक विदेशी कुंजी है और pid अभिनेता आईडी के लिए एक विदेशी कुंजी है।

ध्यान दें कि प्रश्न पर प्रतिबंध मुझे temp टेबल या रिकर्सन का उपयोग करने से रोकते हैं: क्वेरी उप-चयनों के साथ की जानी चाहिए।


मैं भी

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

सबक्वेरी समझदार जवाब, कम से कम वापसी:


मैं अंत में कुछ काम कर कोड पाने में कामयाब रहे। लेकिन यह हमेशा के लिए ले रहा है। प्रत्येक subquery 30 सेकंड के तहत लिया, लेकिन एक साथ वे 6 मिनट और गिनती ले रहे हैं। क्यूं कर?


नोट: यह मुझे होमवर्क के रूप में दिया गया था। मेरे हिस्से पर अकादमिक दुर्व्यवहार के किसी भी समानता से बचने के लिए, मैं पसंद करूंगा कि अगर लोग पूर्ण/सटीक समाधान पोस्ट नहीं करते हैं, बल्कि सामान्य चीजों को इंगित करते हैं कि मैं गलत कर रहा हूं/सामान्य सुझाव देता हूं कि मुझे इसके बारे में कैसे जाना चाहिए ।

+2

@AbeMiessler http://sqlfiddle.com/ – scottm

+0

एक टेस्ट केस बनाने: के साथ डेटा – cetver

+0

ओह अस्थायी टेबल बना, और यहाँ मैं सिर्फ पता लगा कि कैसे एक पुनरावर्ती CTE के साथ यह करने के लिए भी (इस में दिलचस्प था चक्रीय ग्राफ से निपटने का संदर्भ) ... आप उन्हें उपयोग करने की अनुमति क्यों नहीं दे रहे हैं? हालांकि, इस तरह की चीज़ों पर बेहतर प्रदर्शन करने वाले कुछ नए गैर-एसक्यूएल डेटाबेस नहीं हैं - हालांकि मैंने किसी को नेटवर्क-ग्राफ़ डेटाबेस बनाया है? क्या आपको सीटीई का उपयोग करने की इजाजत है? –

उत्तर

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

इसके अलावा, आप वैसे भी यहाँ पुनरावर्ती सीटीई का उपयोग उन का उपयोग कर एक जवाब है की अनुमति नहीं है के रूप में प्रयोग करेंगे एक समाधान का चित्र देने के लिए।

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

+0

हम्म यह अभी भी एक वास्तविक उत्तर है, जो मुझे लगता है कि वह इससे बचना चाहता था। – ErikE

+0

यह एक वास्तविक उत्तर है, लेकिन मैंने उत्तर पोस्ट करने के बाद उस टिप्पणी को पोस्ट किया, तो यह ठीक है। – Colleen