-1

所以问题是:

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')

但后来我在想我是如何只选择一个至少有一个英国成员的乐队。这并不一定意味着每个人都是英国人。有人可以帮忙想办法查询某个乐队的所有成员以检查他们是否都是英国人吗?

4

2 回答 2

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.

但是你真的应该习惯JOIN在 SQL 中使用。尝试在没有 SQL 的情况下JOIN进行编程就像在没有while. 它不仅是 SQL 语言的基本组成部分,而且在许多情况下它的性能更好。YMMV;根据您的数据测试这两种解决方案。

于 2013-07-16T22:34:34.787 回答
0

这是一个使用group by. 我更喜欢将group byandhaving用于“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.

于 2013-07-16T23:28:32.347 回答