如何查询表格中的内容,同时排除其他内容

时间:2016-07-20 05:08:55

标签: mysql sql

嘿,我是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 

似乎我正在制作电影,但其中一些是电影,其中两个演员都在场,这是我不想要的。我不确定我做错了什么。非常感谢任何帮助和解释!

2 个答案:

答案 0 :(得分:1)

你可以对每部电影使用条件聚合来检查一部电影是否同时出现Kevin Bloom和Adam Grant,或者都没有。为了确保在逻辑上正确地执行对某人的检查,您应该将检查括在括号中。

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

答案 1 :(得分:0)

蒂姆的出色解决方案。但是不可能在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