这是问题陈述:找到在战斗中失去所有船只的国家。
数据库描述为: enter image description here 简短的数据库描述“船舶”
正在考虑参加第二次世界大战的海军舰船数据库。该数据库包含以下关系:
Classes(class, type, country, numGuns, bore, displacement)
Ships(name, class, launched)
Battles(name, date)
Outcomes(ship, battle, result)
班级中的所有船舶都具有相同的总体设计。通常为类分配根据相应设计建造的第一艘船的名称,或与数据库中任何船名不同的名称。将其名称指定给某类的船称为领队。
“类别”关系包括类别名称,类型(战斗舰可以是bb,战斗巡洋舰可以是bc),舰艇的制造国家,主炮数量,枪口径(口径)英寸)和位移(重量以吨为单位)。
“船舶”关系保存有关船舶名称,其相应类别的名称以及船舶下水年份的信息。
“战斗”关系包含舰船参加的战斗的名称和日期。
结果关系-给定船的战斗结果(可能是沉没,损坏或确定,最后一个值表示该船在不受伤害的情况下幸存下来)。
注意:
“结果”关系可能包含“船舶”关系中不存在的船舶。
沉没的船无法参加以后的战斗。
出于历史原因,在许多演习中,牵强舰被称为总舰。
在数据库中仍然考虑在“结果”表中找到但在“船”表中找不到的船。即使沉没也是如此。
这是我的代码:
select country
from Classes left join Ships
on classes.class=ships.class
right join Outcomes
on Classes.class=ship
or ships.name=ship
where ship in (select ship from outcomes where result = 'sunk')
group by country
;
我的结局是日本德国,而无效的结局应该只是德国
答案 0 :(得分:1)
似乎诀窍是在您的原始查询中添加and not exists (select 0 from ships where name = o.ship)
,不包括“船舶”表中不存在的船舶,当然“国家/地区”列的值不应为null,因为会询问相关国家/地区。因此,请考虑使用:
select country
from Classes c
left join Ships s
on c.class = s.class
right join Outcomes o
on c.class = ship
and not exists (select 0 from ships where name = o.ship)
and o.result = 'sunk'
where c.country is not null
group by country;
btw,使用ship in (select ship from outcomes where result = 'sunk')
是多余的,and o.result = 'sunk'
就足够了。
答案 1 :(得分:0)
我会使用having
子句:
select c.country
from classes c join
Ships s
on c.class = s.class left join
outcomes o
on o.ship = s.name
group by c.country
having count(distinct s.name) = count(distinct case when o.result = 'sunk' then s.name end);
答案 2 :(得分:0)
我将每个国家的船只与每个国家沉没的船只进行了比较,我对它们进行了过滤以仅显示两个表中数量相同的国家
WITH ALL_SHIPS AS (
SELECT ship, country from outcomes o
JOIN classes c ON (c.class = o.ship)
UNION
SELECT name, country FROM ships s
JOIN classes c ON (c.class = s.class)
),
SHIPS_PER_COUNTRY AS (
SELECT country, COUNT(ship) count FROM ALL_SHIPS
GROUP BY country
),
SHIPS_SUNK AS (
SELECT ship, result FROM outcomes
WHERE result = 'sunk'
),
SHIPS_SUNKED_PER_COUNTRY AS (
SELECT aships.country, COUNT(ssunk.result) count FROM ALL_SHIPS aships
JOIN SHIPS_SUNK ssunk ON (ssunk.ship = aships.ship)
GROUP BY aships.country
)
SELECT spc.country FROM SHIPS_PER_COUNTRY spc
JOIN SHIPS_SUNKED_PER_COUNTRY sspc ON (sspc.country = spc.country)
WHERE spc.count = sspc.count