所以问题是:
fan(fanID: integer, fanName: string)
band(bandID: integer, bandName: string)
likes(fanID: integer, bandID: integer)
bandMember(memID: integer, memName: string, bandID: integer, nationality: string)
(a)列出只有英国成员的乐队的名字。
起初我以为我想出了这个解决方案:
Select bandname
from band
where band.id NOT IN
(select bandMember.id
from bandMember
where nationality <> 'British')
然后我在想我是如何选择一个至少有一个英国成员的乐队。这并不一定意味着每个人都是英国人。有人可以帮助想办法查询某个乐队的所有成员,以检查他们是否都是英国人?
答案 0 :(得分:3)
加入乐队成员,但仅限非英国会员。使用OUTER JOIN执行此操作,在连接条件中指定国籍非常重要。然后,如果没有匹配,外连接将返回bandMember的所有列为null。
SELECT b.bandname
FROM band b
LEFT OUTER JOIN bandMember m
ON b.bandID = m.bandID AND m.nationality <> 'British'
WHERE m.bandID IS NULL
重新评论:
上述查询应与以下查询等效:
SELECT b.bandname
FROM band b
WHERE b.bandID NOT IN
(SELECT bandID FROM bandMember WHERE nationality <> 'British')
这与您最初的想法略有不同,但我将bandId
与bandId
进行比较。
但是你应该习惯在SQL中使用JOIN
。尝试在没有JOIN
的情况下在SQL中编程就像尝试在没有while
的大多数其他语言中编程一样。它不仅是SQL语言的基本组成部分,而且在许多情况下性能更好。因人而异;根据您的数据测试两种解决方案。
答案 1 :(得分:0)
以下是使用group by
的解决方案。我更喜欢将group by
和having
用于“set-within-a-set”子查询:
select b.bandname
from band b join
bandmember bm
on b.id = bm.bandid
group by b.bandname
having sum(case when bm.nationality <> 'British' then 1 else 0 end) = 0;
这个解决方案的优点在于它非常容易适应。假设你想要一个至少有两名英国成员的乐队:
having sum(case when bm.nationality = 'British' then 1 else 0 end) >= 2;
顺便说一句,您的查询根本不起作用,因为您要将band.id
与bandMember.id
进行比较。内部选择应为bandId
。