没有预期的结果;找到保留所有名为Interlake的船只的水手的名字

时间:2017-11-20 17:27:28

标签: sql-server

这些是3张桌子(水手,船只,储备),我想知道保留两条夹层船(101,102)的水手.BID应该由电脑计算

`select * from sailors
 where sid in(select sid from reserves
  inner join boats on reserves.bid = boats.bid
  where boats.bname='Interlake')`

查看表格https://i.stack.imgur.com/hfHpH.png图片的链接 或链接到pdf表格http://www.cs.toronto.edu/~avaisman/csc343summer/tutorials/Tutorial_5.pdf

结果= dustin luber horatio 期待=尘土飞扬 谢谢你的帮助

4 个答案:

答案 0 :(得分:0)

您可以使用以下

<强>解释

  1. 使用cte report
  2. 了解名称= interlake的船只数量
  3. 使用摘要cte
  4. 查找所有使用名称interlake保留船只的水手
  5. 查找所有保留所有船只的水手
  6. 查询

    declare @boat varchar(50) = 'Interlake'
    
    ;with report as (
     select bname,count(*) as [Count]
     from boats b  
     where b.bname=@boat
     group by b.bname
    ), summary as(
      select s.sname, b.bname, count(*) as [Count]
      from sailors s
      inner join reserves r on r.sid = s.sid
      inner join boats b on b.bid = r.bid
      where b.bname=@boat
      group by s.sname,b.bname
    )
    
    select s.*
    from  summary s
    inner join report r on r.bname = s.bname and r.[Count] = s.[Count]
    

    这是一个有效的demo

    希望这会对你有所帮助

答案 1 :(得分:0)

以下SQL将构建临时表变量,填充它们然后使用连接来向您显示哪些水手已经预留了InterLake船。

- 构建水手临时表变量并插入测试数据

declare @sailors table
([sid]  int
,[name] varchar(50))
insert into @sailors
([sid],[name])
values
(1,'Sailor One'),
(2,'Sailor Two'),
(3,'Sailor Three')

- 构建临时表变量并插入测试数据

declare @boats table
(bid    int
,[name] varchar(50))
insert into @boats
(bid,[name])
values
(1,'10 foot John Boat'),
(2,'14 foot John Boat'),
(3,'18 foot Ski Boat'),
(4,'Interlake')

- 构建保留临时表变量并插入测试数据

declare @reserves table
(rid    int
,[sid]  int
,bid    int)
insert into @reserves
(rid,[sid],bid)
values
(1, 1, 4),
(2, 3, 1),
(3, 2, 4)

- 查询选择哪些水手已预留Interlake船

select      s.name as Sailor
            ,b.name as Boat
from        @sailors s
inner join  @reserves r on r.[sid] = s.[sid]
inner join  @boats b on b.bid = r.bid
where       b.name = 'InterLake'

- 结果

Sailor      Boat
Sailor One  Interlake
Sailor Two  Interlake

答案 2 :(得分:0)

首先,我们将加入两个表格,其中水手sid匹配储备sid和出价为101或102的地方,因为这是Interlake的出价。如果你想通过where bname = interlake来做,你将把船加入储备。这是您使用inner join在原始查询中完成的操作。我选择使用左:

select s.*
from sailors s
left join reserves r on r.sid = s.sid
where r.bid in (101, 102)

现在我有所有人都保留了101或102号船。我想过滤掉那些只有两者的人。在这种情况下,我想从我的过滤结果中查询。我决定使用派生表,但你也可以使用cte。

类似的东西:

select *
from
(select s.*
from sailors s
left join reserves r on r.sid = s.sid
where r.bid in (101, 102)) t1 --t1 is the alias 

但我不希望这个过滤表中的所有内容。我想要名字。

select sname
from
(select s.*
from sailors s
left join reserves r on r.sid = s.sid
where r.bid in (101, 102)) t1

但我只想要那些租用101和102的人的名字。在这种情况下,如果按照名字计算,这意味着如果你的数量大于1,你只能租用两者:

select sname --select the column of names I want
       ,count(sname) as total --here's the count of names, completely optional
from 
(select s.*
from sailors s
left join reserves r on r.sid = s.sid
where r.bid in (101, 102)) t1
group by sname --anything you use an aggregation you'll need to likely group by something
having count(sname)  > 1 --my filter after I group my names

以下是您可以使用的rextester示例。

答案 3 :(得分:0)

SELECT DISTINCT S.SID,S.SNAME,S.RATING,S.AGE
FROM  SAILORS S,RESERVES R,BOATS B 
WHERE  S.SID=R.SID AND  R.BID=B.BID
AND NOT EXISTS
          ((SELECT  B.BID
             FROM  BOATS B WHERE B.BNAME NOT LIKE '%INTERLAKE%')
            EXCEPT
             (SELECT  R.BID
              FROM  RESERVES R
              WHERE  R.SID=S.SID))
相关问题