2015-05-21 33 views
0

我正在嘗試在sqlzoo.net上回答問題#12 (http://sqlzoo.net/wiki/More_JOIN_operations)。我無法自己找出答案,但我確實設法在網上找到答案。SQLZOO#12 - 對多個select和join語句感到困惑

12:「John Travolta」最忙碌的年份,顯示了他每年製作超過2部電影的年份和電影數量。

答:

SELECT yr,COUNT(title) FROM 
    movie JOIN casting ON movie.id=movieid 
     JOIN actor ON actorid=actor.id 
WHERE name='John Travolta' 
GROUP BY yr 
HAVING COUNT(title)=(SELECT MAX(c) FROM 
(SELECT yr,COUNT(title) AS c FROM 
    movie JOIN casting ON movie.id=movieid 
     JOIN actor ON actorid=actor.id 
WHERE name='John Travolta' 
GROUP BY yr) AS t) 

一個部分,我不完全理解的是多個聯接:

FROM movie 
JOIN casting ON movie.id=movieid 
JOIN actor ON actorid=actor.id 
  1. 演員正在與電影才加入,或者是演員正在加入電影JOIN鑄造
  2. 我想找到一個網站,解釋複雜的加入聲明,因爲我的嘗試答案是遠遠不正確的(缺少許多部分)。我認爲具有多個複雜聯接語句的子選擇語句目前有點令人困惑。但是,我無法找到一個好的網站來打破這些信息,幫助我形成自己的疑問。

另一部分我不完全理解是這樣的:

(SELECT yr,COUNT(title) AS c FROM 
     movie JOIN casting ON movie.id=movieid 
      JOIN actor ON actorid=actor.id 
    WHERE name='John Travolta' 
    GROUP BY yr) AS t) 

3.什麼是上面的代碼試圖找到?

+0

@卡里我搜索了「聯接解釋」,並找到這篇文章http:// stackoverflow。COM /問題/ 2612296 /請-解釋-ME-的mysql-加入功能於簡單的語言。希望這會讓你開始。關於子查詢,只要將它們視爲常規查詢,除了「包裝」查詢將直接作用於子查詢返回的任何內容。希望這可以幫助。 –

回答

0

好吧,很高興你不害怕問,我會盡我所能幫助澄清正在發生的事情......請原諒我重新格式化查詢,以我的編寫查詢的思維。它更好地展示了事情來自何處的關係(我的觀點),並可能對你有所幫助。

關於我的重寫的其他一些事情。我也喜歡對錶使用別名引用,所以每一列都使用源自它的表(或別名)進行限定。它可以防止模糊,特別是對於不瞭解表結構和表之間關係的人。 (m =電影的別名,c =鑄造的別名,a =演員表的別名)。對於子查詢,並保持別名混淆清晰,我後綴2,如m2,c2,a2。

SELECT 
     m.yr, 
     COUNT(m.title) 
    FROM 
     movie m 
     JOIN casting c 
      ON m.id = c.movieid 
      JOIN actor a 
       ON c.actorid = a.id 
    WHERE 
     a.name = 'John Travolta' 
    GROUP BY 
     m.yr 
    HAVING 
     COUNT(m.title) = (SELECT MAX(t.movieCount) 
          FROM 
          (SELECT m2.yr, 
             COUNT(m2.title) AS movieCount 
            FROM 
            movie m2 
             JOIN casting c2 
              ON m2.id = c2.movieid 
              JOIN actor a2 
               ON c2.actorid = a2.id 
            WHERE 
            a2.name='John Travolta' 
            GROUP BY 
            m2.yr) AS t 
        ) 

首先,看的最外層查詢(別名M,C,A)和最內層查詢(別名平方米,C2,A2)幾乎是一致的。

查詢必須先從最深的查詢中運行...在這種情況下,m2,c2,a2查詢。看看它,看看IT將要提供什麼。如果你這樣做了,那麼每年他都會有一部電影,並且電影的數量......從他們的樣本數據開始的結果從1976年一直延續到2010年。到目前爲止,本身沒有什麼複雜的(大約20行)。現在,由於每個表都可能有一個別名,每個子查詢(例如這個必須有一個別名,所以這就是爲什麼「as t」)。所以,沒有真正的表,它包裝整個查詢的結果集並分配認爲「T」。

所以現在的別名,轉到上一級查詢中還包裹在括號...

SELECT MAX(t.movieCount) 
    FROM (EntireSubquery as t) 

儘管縮寫,這是發動機在做什麼。綜觀子查詢結果給出了一個別名「t」,並找到最大的「movieCount」值,這是在給定年份中完成的電影的數量,在這種情況下,實際數量是3,我們差不多完成了。現在,再次向最外層的查詢...這與最內層的查詢幾乎相同。唯一的區別是HAVING子句。這是在每年執行所有分組後應用的。然後它將每年的IT行結果集計數與SELECT MAX(t.movi​​eCount)的3值結果進行比較...

因此,只有1或2部電影的所有年份都被排除在結果之外,並且只有包含3部電影的一年。

現在,澄清聯接。每個表都應該與一個或多個表(也稱爲鏈接表,如同時具有電影和演員的演員表)建立關係,因此,請將聯結視爲如何按順序放置表,以便每個人都可以觸摸一塊到另一個,直到我將它們全部鏈接在一起。在這種情況下,

電影 - >通過電影ID鏈接的投射,然後投射 - > actor通過actor ID,這樣我就可以做到它在視覺層次上...我從電影表開始,加入基於電影ID =演員電影ID的演員表。現在,從演員表加入基於普通演員ID字段的演員表

FROM 
     movie m 
     JOIN casting c 
      ON m.id = c.movieid 
      JOIN actor a 
       ON c.actorid = a.id 
FROM 
     movie m 
     JOIN casting c 
      ON m.id = c.movieid 
      JOIN actor a 
       ON c.actorid = a.id 

現在,這是一個簡單的關係IP,但你可以有一個主表和多個子級表。您可以根據各自的數據加入多個表格。非常簡單的樣本來澄清這一點。你有一張學生桌去學校。學生擁有學位專業,種族,地址狀態(假設在線學校和學生可以來自任何州)。如果您已經爲度,種族查找表和狀態,你可能會想出像...

select 
     s.firstname, 
     s.lastname, 
     d.DegreeDescription, 
     e.ethnicityDescription, 
     st.stateName 
    from 
     students s 
     join degrees d 
      on s.degreemajor = d.degreeID 
     join ethnicity e 
      on s.ethnicityID = e.id 
     join states st 
      on s.homeState = st.stateID 

注意,每個表直屬,學生相關的層次表示。並不是所有的表格都需要比上一個更深。

因此,有許多網站,如馬克提供的w3schools,但學會一次解剖小塊...什麼是從點A到點Z的最小表格?並繪製關係。然後,根據您要查找的要求標準進行減重。

+0

哇,謝謝你花時間輸入所有這些!學生/學校的例子實際上是超級有用的,我沒有意識到你可以像這樣加入表格。其實,一旦我閱讀了學生/學校的例子,你的帖子中的其他內容都是有道理的。謝謝! – Karrie

0

正確的答案應該是:

SELECT yr, COUNT(title) 
FROM movie m 
JOIN casting c ON m.id=c.movieid JOIN actor a ON c.actorid=a.id 
WHERE name='John Travolta' 
GROUP BY yr 
HAVING COUNT(title) > 2; 

你發現了(這似乎是在sqlzoo網站錯誤)的答案是尋找有等於一年的最高計數的計數任何一年。

我在上面的查詢中使用了表別名來清除表的連接方式。電影被加入到演員中,並且演員被加入到演員中。

迷惑你的子查詢將列出每年以及明星John Travolta的那一年的電影數量。如果你以書面形式回答問題,則不需要。

至於學習資源,請確保您已經掌握了基本知識。在http://w3schools.com/sql瞭解一切。嘗試在您最喜歡的搜索引擎中搜索「sql join multiple tables」,當您準備好更多時。

+0

儘管您的查詢確實得到了正確的答案,但您在HAVING子句中提供了明確的值> 2.是的,對於電影和演員/女演員在一年中執行超過2次操作可能是極端的,但是對於底層基礎寫查詢...如果數量較大,比如庫存和最大銷售產品可能有200多個?您可能有許多商品有200多個銷售,因此查詢期望最高的數量(其巧合僅爲3)。他們需要更多的澄清來了解正在發生的事情。 – DRapp

+0

@DRapp,我不明白你的觀點。這個問題提供了一個明確的價值(「他製作了超過2部電影」),因此查詢中需要明確的值。而且由於它說「超過」,必須使用大於運算符,而不是等號。 –

+0

你是對的,並且它會在這種情況下提供正確的答案......但我不是隻回答一個問題,而是試圖澄清將它帶到更廣泛的上下文中以實際獲取MAX()值。如果有幾年的時間,3,4或5部電影完成了會怎樣。你會得到3個答案,他們只關心5部電影存在的年份。因此,電影演示使用了=(從...中選擇max()...)應用於它。 – DRapp