嘿,我是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 :(得分: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