2013-03-17 29 views
2

我正在與電影數據庫進行更多的JOIN操作。我的問題是關於問題#16:列出所有曾與'藝術加芬克爾'合作過的人SQLzoo more JOIN execerise#16

您需要首先獲取Art Garfunkel所在的所有電影作爲一個值,然後獲取所有名爲通過將它與第一個值進行比較來看相同的電影。

我想到了我自己的查詢,並通過邏輯它應該工作,但不會因超時(這我假設是由於低效的查詢)

我的查詢:

SELECT DISTINCT a.name 
FROM actor a 
JOIN casting b ON (a.id=b.actorid) 
JOIN movie c ON (b.movieid=c.id) 
WHERE c.title IN(SELECT z.title 
FROM movie z 
JOIN casting y ON (z.id=y.movieid) 
JOIN actor x on (y.actorid=x.id) 
WHERE x.name='Art Garfunkel') 

另一個版本:

SELECT DISTINCT actor.name 
FROM movie,actor,casting 
WHERE movie.id=casting.movieid 
AND actor.id=casting.actorid 
AND movie.title IN(SELECT movie.title 
FROM movie,actor,casting 
WHERE movie.id=casting.movieid 
AND actor.id=casting.actorid 
AND actor.name='Art Garfunkel') 

這些都拋出一個解析錯誤說,有一個超時試圖查詢任何如上圖所示。

的,他們提供的查詢的版本,被公認是一種回答是:

SELECT DISTINCT d.name 
FROM actor d JOIN casting a ON (a.actorid=d.id) 
    JOIN casting b ON (a.movieid=b.movieid) 
    JOIN actor c ON (b.actorid=c.id 
       AND c.name='Art Garfunkel') 
    WHERE d.id!=c.id 

是我的邏輯完全錯了嗎?或者說這個查詢是非常非常低效的(我在想這個)。有沒有辦法解決它運行並得到正確的答案?或者我應該更正確地考慮正確的查詢方式嗎?

這麼多的問題,但我想要反饋爲什麼該查詢不起作用,下一步是什麼。

回答

1

這裏有你所有的SQL動物園問題: answers

SELECT a.name 
FROM casting c JOIN actor a ON 
    a.id = c.actorid 
WHERE 
    a.name <> 'Art Garfunkel' AND 
    c.movieid 
IN (
    SELECT m.id 
    FROM casting c JOIN movie m ON 
     m.id = c.movieid 
    JOIN actor a ON 
     c.actorid = a.id 
    WHERE a.name = 'ART Garfunkel' 
) 
ORDER BY a.name 
+0

給定的查詢實際上也不起作用。它返回上面提到的相同的分析錯誤。這就是爲什麼我很困惑,爲什麼我提到的底部查詢工作,但我寫的兩個沒有 – Paul 2013-03-17 22:40:34

+0

即時通訊不知道對不起 – Hamoudy 2013-03-17 22:49:42

+0

這是他們的錯誤,嘗試用他們的電子郵件發送郵件 – Hamoudy 2013-03-17 23:09:54

0

好,我花了幾個小時,真的明白這一個(數16)出來,作爲建議的解決方案一見鍾情(二)都沒有意義。 然而,在我想出了我自己的解決方案後,我設法解決了這個問題,這是更容易理解的(我覺得)。 所以首先我的解決辦法:

select name from actor 
join casting on actor.id=actorid 
where movieid in 
(select movieid from casting 
join actor on actorid=actor.id 
where name='Art Garfunkel') 
and name <>'Art Garfunkel' 

我搜索所有actorids(=外選擇)對於那些movieids在藝術加芬克爾有一個角色(內選),然後我篩選出藝術加芬克爾自己。

夠簡單。

你可以在查詢的結尾處添加以下線,這將是不錯:

order by name 

但隨後的查詢不被接受不再是正確的。

因爲當我不明白別人的解決方案時,我會煩惱我,我花了一些時間在其他地方給出的。 這又是:

SELECT DISTINCT a.name 
FROM actor a 
JOIN casting b ON (a.id=b.actorid) 
JOIN casting c on b.movieid=c.movieid 
JOIN actor d ON (c.actorid=d.id 
       AND d.name='Art Garfunkel') 
WHERE a.id!=d.id 

有趣的是,你可以寫這個略有不同,採取的where子句出最後的加盟:

SELECT DISTINCT a.name 
FROM actor a 
JOIN casting b ON (a.id=b.actorid) 
JOIN casting c on b.movieid=c.movieid 
JOIN actor d ON (c.actorid=d.id) 
WHERE d.name='Art Garfunkel' 
AND a.id!=d.id 

在任何情況下,你必須看看這個查詢反過來,否則它從來沒有道理。 這似乎是發生了什麼:

演員-d(或Where子句,這似乎是第一部分首先要評估)集(或限制)藝術加芬克爾,並將此回casting- c鑄造-C查找從藝術加芬克爾的movieids(其中的方式有​​兩種:1412漁獲-22和1597拳擊海倫娜),並且將這些作爲一個過濾器爲鑄造-B -as 鑄造-B接管他們。 Casting-b然後 - 將過濾器設置爲來自Garfunkel的那兩部電影 - 返回到actor-a中的所有actorid,其中查找了在這兩部電影中加星標的所有演員的名字。最後,Art Garfunkel被濾除了 - 就是這樣。

感覺我好像這是一些機器代碼,就好像某些查詢優化器已經提出了它一樣。 明智的人不會考慮這些方面(至少我不會)。

0
SELECT name 
    FROM movie, casting, actor 
    WHERE movieid=movie.id 
    AND actorid=actor.id 
and movieid IN 
    (SELECT movieid FROM casting, actor 
    WHERE actorid=actor.id 
    AND name='Art Garfunkel')and name <>'Art Garfunkel' 
+0

雖然這段代碼可能會回答這個問題,但幾個解釋詞將有助於當前和未來的讀者更好地理解這個答案。 – Thom 2015-05-07 11:13:08

0

以下是上面給出的SQL答案:

SELECT a.name from actor a 
inner join casting c on a.id=c.actorid 
inner join movie m on m.id=c.movieid 
WHERE m.id in (SELECT c.movieid from casting c inner join actor a 
on a.id=c.actorid WHERE a.name='Art Garfunkel') 
and a.name<>'Art Garfunkel' 

然而,正如誰仍習慣工會一個SQL初學者,我想出了第一個代碼是以下幾點:

SELECT name from actor WHERE id IN 
(SELECT actorid from casting WHERE movieid IN (SELECT movieid 
from casting WHERE actorid IN (SELECT 
id from actor WHERE name='Art Garfunkel'))) 
and name<>'Art Garfunkel' 

它基本上和上面的解釋一樣 - SELECT id聲明發現Art的演員id。 SELECT movieid找到他所在的電影。SELECT actorid找到那些電影中的其他演員,而SELECT名稱找到了他們的名字。

學習如何進行聯合是理想的,我最終得到了內部聯接語法,但只是將其他答案引入了更適合SELECT的SQL用戶或仍在學習工會。

0

另一種解決方案,工程如下:

SELECT name 
FROM casting 
JOIN actor ON actor.id=actorid 
WHERE movieid IN (SELECT movieid FROM casting WHERE actorid = 
    (SELECT id FROM actor WHERE name='Art Garfunkel')) 
GROUP BY actorid 
HAVING name<>'Art Garfunkel' 
0

我認爲這個問題是類似朱莉·安德魯斯項目(上sqlzoo#13目前),所以我已經基本適應Bill Karwin S」優雅solution to the Julie Andrews problem到用一種不那麼優雅的方式來解決這個問題。此解決方案確實使用了所有JOINs,這似乎是這組練習的要點。從本質上講,我將這個概念化的方式是,藝術加芬克爾出演了一部其他人也參演的電影。換句話說,Garfunkel < - >鑄造< - >電影< - >鑄造< - >合作明星的名字。

我是一個非常新的SQL用戶(老實說,< 24小時)所以這可能是笨重的,但它的工作對我來說:

SELECT a2.name 
FROM actor a1 
JOIN casting AS c1 ON (a1.id = c1.actorid) 
JOIN movie ON (c1.movieid=movie.id) 
JOIN casting AS c2 ON (movie.id=c2.movieid) 
JOIN actor AS a2 ON (c2.actorid=a2.id) 
WHERE 
    a1.name='Art Garfunkel' 
    AND a2.name <> 'Art Garfunkel' 
GROUP BY a2.name 
0

我不明白,爲什麼一個需要加入電影表在這個查詢中。本練習中的任務是僅列出演員姓名,而不是名稱和標題(這也需要加入電影表)。我想出了以下的查詢,它工作。 :)

SELECT name 
FROM actor 
JOIN casting on actor.id = actorid 
WHERE name <> 'Art Garfunkel' 
AND movieid IN 
(SELECT movieid 
FROM casting 
JOIN actor on actorid = actor.id 
WHERE name = 'Art Garfunkel') 
0
SELECT a.name FROM actor a 
    JOIN casting c ON a.id=c.actorid 
    JOIN movie m ON c.movieid=m.id 
    WHERE c.movieid IN 
     (SELECT movieid FROM casting WHERE actorid IN 
      (SELECT id FROM actor WHERE name = 'Art Garfunkel')) 
    AND a.name <> 'Art Garfunkel' 
0

你的這兩種解決方案都不能完全錯誤的。你只需要添加一個條件到你的SQL。 List all the people who have worked with 'Art Garfunkel'它意味着只查找那些與'Art Garfunkel'一起工作的人,但在你的sql中,你不排除'Art Garfunkel'從列表中,這就是爲什麼sqlzoo說你的解決方案是錯誤的。

這裏是你修改的版本:

SELECT DISTINCT a.name 
FROM actor a 
      JOIN casting b ON (a.id=b.actorid) 
      JOIN movie c ON (b.movieid=c.id) 
WHERE c.title IN(SELECT z.title 
        FROM movie z 
           JOIN casting y ON (z.id=y.movieid) 
           JOIN actor x on (y.actorid=x.id) 
        WHERE x.name='Art Garfunkel') 
AND a.name <> 'Art Garfunkel' 

AND a.name <> 'Art Garfunkel'被添加到您的原始SQL

您的解決方案#2:

SELECT DISTINCT actor.name 
FROM movie,actor,casting 
WHERE movie.id=casting.movieid 
     AND actor.id=casting.actorid 
     AND movie.title IN(SELECT movie.title 
          FROM movie,actor,casting 
          WHERE movie.id=casting.movieid 
           AND actor.id=casting.actorid 
           AND actor.name='Art Garfunkel') 
     AND actor.name <> 'Art Garfunkel' 

AND actor.name <> 'Art Garfunkel'被添加到您的原始SQL

0

這個簡單的解決方案是 - select distinct(name) from movie join casting on movie.id=movieid join actor on actor.id=actorid where name not in ('Art Garfunkel') and title in (select title from movie join casting on movie.id=movieid join actor on actor.id=actorid where name ='Art Garfunkel')

+0

儘管這段代碼可能會回答這個問題,但有幾句解釋會幫助當前和未來的讀者更好地理解這個答案。 – xskxzr 2018-01-31 09:13:07