@djdoomer

djdoomer

Sergey
djdoomer

Вечно чем-то недоволен

21 я читаю 21 меня читают
278 постов
181 комментариев
djdoomer
01 Jul 2019

Никак не могу решить задачу по SQL. В общем, есть вот такая база:
https://prnt.sc/o9517c
Текст задания: Определить страны, которые потеряли в сражениях все свои корабли.
Верный ответ:
https://prnt.sc/o9528v
Есть еще проверочная база, с другими данными.
Мое решение дает верный ответ по текущей базе, но не проходит по проверочной.
SELECT DISTINCT classes.country
FROM classes JOIN outcomes
ON classes.class=outcomes.ship
WHERE classes.country IN (SELECT DISTINCT classes.country
FROM classes JOIN outcomes
ON classes.class=outcomes.ship
WHERE outcomes.result='sunk')
Подскажите, где я могу ошибаться?
Если что, это 47 задача отсюда http://sql-ex.ru/learn_exercises.php

Рекомендовано: skobkin-ru
01 Jul 2019

По-моему, в условии джойна как минимум, ты сравниваешь имя корабля с классом.

Там могут быть классы, которые не совпадают ни с одним именем корабля, а в одном классе могут быть корабли с разными именами, плюс еще мильен неудобных условий, например, один корабль мог ходить в бой много раз, но потопиться только в последнем.

Но я и сама не смогла, увидела, что как-то условий много, тестового материала мало, и бросила.

У меня тут тоже куча условий не учтена, а результат тестовая база выдает верный:

select distinct c.country from (
select  o.ship tmp_ship_name, s.class tmp_class, o.battle, o.result 
from outcomes o
left outer join ships s on o.ship = s.name

union

select  o.ship tmp_ship_name, o.ship tmp_class, o.battle, o.result 
from outcomes o
where o.ship not in (select distinct name from ships)
) u

join classes c on u.tmp_ship_name = c.class
where lower(u.result) not in ('ok', 'damaged')
Комментарий был отредактирован в 23:03:56 01.07.2019
#mdsse/1
02 Jul 2019

Я бы считал сумму кораблей классов страны и сумму потопленных кораблей этих классов.

Если корабля нет в ships - у него нет связи со страной, можно его не рассматривать. Корабль после потопленния второй раз не плывёт, значит опять же достаточно посчитать только потери с именами, имеющимися в таблице ships.

#mdsse/2 в ответ на /1
02 Jul 2019

Я тоже думала как-то так решить, но потом подумала, что в ships корабля может и не быть, но класс может называться по имени корабля, и связь со страной таким образом все равно есть.

#mdsse/3 в ответ на /2
02 Jul 2019

hildisvini, вот в итоге какое у меня решение вышло

WITH out AS (SELECT *
FROM outcomes JOIN (SELECT ships.name s_name, classes.class s_class, classes.country s_country
FROM ships FULL JOIN classes
ON ships.class = classes.class
) u
ON outcomes.ship=u.s_class
UNION 
SELECT *
FROM outcomes JOIN (SELECT ships.name s_name, classes.class s_class, classes.country s_country
FROM ships FULL JOIN classes
ON ships.class = classes.class
) u
ON outcomes.ship=u.s_name)

SELECT fin.country
FROM (
SELECT DISTINCT t.country, COUNT(t.name) AS num_ships
FROM (
select distinct c.country, s.name
from classes c
inner join Ships s on s.class= c.class
union
select distinct c.country, o.ship
from classes c
inner join Outcomes o on o.ship= c.class) t
GROUP BY t.country

INTERSECT

SELECT out.s_country, COUNT(out.ship) AS num_ships
FROM out
WHERE out.result='sunk'
GROUP BY out.s_country) fin
#mdsse/5 в ответ на /1
02 Jul 2019

Круто! У меня терпения не хватило допилить.

Надо будет порешать там задачки, раз все равно зарегистрировалась

#mdsse/6 в ответ на /5

Добавить пост

Вы можете выбрать до 10 файлов общим размером не более 10 МБ.
Для форматирования текста используется Markdown.