【问题标题】:Need guidance on SQL query需要有关 SQL 查询的指导
【发布时间】:2013-07-17 08:01:38
【问题描述】:

所以问题是:

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

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

【问题讨论】:

  • fanlikes 表与这个问题有什么关系?您指的是上面查询中的select bandMember.bandID 吗?

标签: sql database schema relational


【解决方案1】:

加入乐队的成员,但仅限非英国成员。使用 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')

这与您最初的想法略有不同,但我将bandIdbandId 进行比较。

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

【讨论】:

  • 非常感谢您的帮助。有没有办法在不使用 ON 的情况下做到这一点?再次感谢。
【解决方案2】:

这是一个使用group by 的解决方案。我更喜欢将group byhaving 用于“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.idbandMember.id 进行比较。内部选择应该是bandId

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-19
    • 1970-01-01
    • 2011-02-22
    • 2017-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多