Top.Mail.Ru
Ответы

Помогите с решением задачи 12-ой (Shurgenz: 2005-01-02) DML на sql-ex

Есть следующая БД (описание прямо с сайта, с сохранением стиля):

Рассматривается БД кораблей, участвовавших во второй мировой войне. Имеются следующие отношения:
Classes (class, type, country, numGuns, bore, displacement)
Ships (name, class, launched)
Battles (name, date)
Outcomes (ship, battle, result)
Корабли в «классах» построены по одному и тому же проекту, и классу присваивается либо имя первого корабля, построенного по данному проекту, либо названию класса дается имя проекта, которое не совпадает ни с одним из кораблей в БД. Корабль, давший название классу, называется головным.
Отношение Classes содержит имя класса, тип (bb для боевого (линейного) корабля или bc для боевого крейсера), страну, в которой построен корабль, число главных орудий, калибр орудий (диаметр ствола орудия в дюймах) и водоизмещение ( вес в тоннах). В отношении Ships записаны название корабля, имя его класса и год спуска на воду. В отношение Battles включены название и дата битвы, в которой участвовали корабли, а в отношении Outcomes – результат участия данного корабля в битве (потоплен-sunk, поврежден - damaged или невредим - OK).
Замечания. 1) В отношение Outcomes могут входить корабли, отсутствующие в отношении Ships. 2) Потопленный корабль в последующих битвах участия не принимает.

Сам запрос:
Добавить отсутствующие в таблице Ships головные корабли из Outcomes. Годом спуска на воду считать средний округленный до целого числа год по кораблям страны добавляемого корабля. Если средний год неизвестен, запись не вносить.

Моё решение:
WITH HeadShips AS (
SELECT o.ship, s.class
FROM Outcomes o
JOIN Ships s ON o.ship = s.name
WHERE s.class = o.ship
GROUP BY o.ship, s.class
)
, AverageYear AS (
SELECT s.class, c.country , ROUND(AVG(s.launched), 0) AS avg_year
FROM Ships s
JOIN Classes c ON s.class = c.class
GROUP BY s.class, c.country
)
INSERT INTO Ships (name, class, launched)
SELECT h.ship, h.class, a.avg_year
FROM HeadShips h
JOIN AverageYear a ON h.class = a.class
LEFT JOIN Ships s2 ON h.ship = s2.name AND h.class = s2.class
WHERE a.avg_year IS NOT NULL
AND s2.name IS NULL;

Ошибка в том, что этот код проходит основной тест сайта, но не проходит вторичный почему то. Сама таблица идентична правильной (сайт предоставляет правильный ответ). Я уже не знаю, что не так...

По дате
По рейтингу
Аватар пользователя
Ученик
6мес

нужно AVG(CAST(launched AS FLOAT(53)) ) там всякие приколы с автоматическим преобразованием типов в mssql

Аватар пользователя
Ученик
3нед

Уважаемыйkhren_redka_1

Прошу Вас снова удалить эту запись!!! Из за нее забанили людей на sql_ex

Аватар пользователя
Ученик
1мес

Добрый День.
Удалите пожалуйста данный вопрос. Хоть тут и нет ничего криминального, но люди которые используют данный материал далее блокируются на sql-ex. Заранее благодарю.

Аватар пользователя
Знаток
6мес

insert into ships
select ship name,class,launched from
(select distinct ship,c.class,country
from outcomes o
join classes c on c.class=o.ship
where ship not in(select distinct name from ships))
f join
(select country,round(avg(launched*1.0),0) launched
from ships s join classes c on c.class=s.class
group by country) n on f.country = n.country
where n.launched is not null