2016-07-20 35 views
2

嘿,我是SQL新手,我試圖弄清楚如何解決這個問題。我需要列出所有包括Kevin Bloom或Adam Grant在內的電影名單,或者他們都不是。所以基本上我試圖在同一時間顯示所有不兼容的電影。這是我到目前爲止有:如何查詢表格中的內容而排除其他內容

SELECT f.title as 'Films' 
FROM film f 
INNER JOIN film_actor fa ON f.film_id = fa.film_id 
INNER JOIN actor a ON fa.actor_id = a.actor_id 
WHERE (a.first_name != 'Adam' AND a.last_name !='Grant' 
    AND a.first_name = 'Kevin' AND a.last_name = 'Bloom') 
    OR (a.first_name != 'Kevin' AND a.last_name !='Bloom' 
    AND a.first_name = 'Adam' AND a.last_name = 'Grant') 
    OR (a.first_name != 'Kevin' AND a.last_name !='Bloom' 
    AND a.first_name != 'Adam' AND a.last_name != 'Grant) 
GROUP BY f.title 
ORDER BY f.title DESC 

看來,我是製作電影,但他們中的一些電影,其中演員都存在這是我不想要的東西。我不確定我做錯了什麼。任何幫助和解釋,非常感謝!

+0

請給一個嘗試:SELECT film.title FROM演員INNER JOIN FILM_ACTOR ON actor.actor_id = film_actor.actor_id INNER JOIN 膜上film_actor.film_id = film.film_id WHERE(actor.first_name NOT IN('Adam','Kevin'))AND(actor.last_name NOT IN('Grant','Bloom')) – tharif

+0

您能否描述所有表格的結構? –

+0

您是否嘗試過使用CONCAT(a.first_name,a.last_name)的版本? – ldg

回答

1

您可以在每部電影上使用條件聚合來檢查電影是否有凱文布魯姆和亞當格蘭特出現,或者沒有。爲確保對人員的檢查邏輯上正確,您應該將支票放在括號內。

SELECT f.title AS 'Films', 
    SUM(CASE WHEN ((a.first_name = 'Kevin' AND a.last_name = 'Bloom') OR 
        (a.first_name = 'Adam' AND a.last_name = 'Grant')) 
      THEN 1 ELSE 0 END) AS nameMatchCount 
FROM film f 
INNER JOIN film_actor fa 
    ON f.film_id = fa.film_id 
INNER JOIN actor a 
    ON fa.actor_id = a.actor_id 
GROUP BY f.title 
HAVING nameMatchCount = 0  -- both are absent 
    OR nameMatchCount = 2  -- both are present 
ORDER BY f.title DESC 
+0

嘿添,出於某種原因,當我嘗試運行您的查詢時出現錯誤。你也可以解釋HAVING部分嗎? – tntsgoboom

+0

@tntsgoboom由於MySQL正在聚合每個組(這是一組屬於給定影片的記錄集合),因此每次它看到與Kevin Bloom或Adam Grant的記錄時,它都會保持一致。如果對於給定的電影,這個計數器是0,那麼就不會出現,如果它是2,那麼兩者都出現了。 –

+0

我會給一個小提琴,但是你有幾個聯接,並且沒有樣本數據,所以我沒有看到試圖創建一個聯接的重點。 –

0

Tim的優秀解決方案。但在HAVING聲明中不可能提及別名。

WITH CTE_FILM AS 
(
    SELECT 
     [F_ID] 
     ,[F_Name] 
    FROM 
     (VALUES 
      (1, N'Neither Kevin, nor Adam') 
     ,(2, N'Both Kevin and Adam') 
     ,(3, N'Only Kevin') 
     ,(4, N'Only Adam') 
    ) T([F_ID],[F_Name]) 
), 
CTE_FILMACTOR AS 
(
    SELECT 
     [F_ID] 
     ,[A_ID] 
    FROM 
     (VALUES 
         (1, 3),(1, 4) 
     ,(2, 1),(2, 2),(2, 3) 
     ,(3, 1)  ,(3, 3) 
       ,(4, 2)  ,(4, 4) 
    ) T([F_ID],[A_ID]) 
), 
CTE_ACTOR AS 
(
    SELECT 
     [A_ID] 
     ,[A_FirstName] 
     ,[A_LastName] 
    FROM 
     (VALUES 
      (1, N'Kevin', N'Bloom') 
     ,(2, N'Adam' , N'Grant') 
     ,(3, N'Will' , N'Smith') 
     ,(4, N'Chris', N'Pine') 
    ) T([A_ID],[A_FirstName],[A_LastName]) 
) 
SELECT 
    T01.[F_ID] 
    ,T01.[F_Name] 
    ,SUM(CASE WHEN ((T03.[A_FirstName] = 'Kevin' AND T03.[A_LastName] = 'Bloom') OR 
        (T03.[A_FirstName] = 'Adam' AND T03.[A_LastName] = 'Grant')) 
      THEN 1 ELSE 0 END) AS nameMatchCount 
FROM 
    CTE_FILM T01 
    LEFT JOIN CTE_FILMACTOR T02 
    ON 
    T01.[F_ID] = T02.[F_ID] 
    LEFT JOIN CTE_ACTOR T03 
    ON 
    T02.[A_ID] = T03.[A_ID] 
GROUP BY 
    T01.[F_ID] 
    ,T01.[F_Name] 
HAVING 
    SUM(CASE WHEN ((T03.[A_FirstName] = 'Kevin' AND T03.[A_LastName] = 'Bloom') OR 
        (T03.[A_FirstName] = 'Adam' AND T03.[A_LastName] = 'Grant')) 
      THEN 1 ELSE 0 END) = 0 
    OR 
    SUM(CASE WHEN ((T03.[A_FirstName] = 'Kevin' AND T03.[A_LastName] = 'Bloom') OR 
        (T03.[A_FirstName] = 'Adam' AND T03.[A_LastName] = 'Grant')) 
      THEN 1 ELSE 0 END) = 2 
+0

Marcus,OP使用MySQL,至少基於問題的標籤。在MySQL中,可以在'HAVING'子句中使用別名。 –

+0

對不起!上面的腳本是T-SQL –

相關問題