Книги и статьи по SQL Rambler's Top100 Switch language to: English 29 октября 2020 г. 4:38:54


www.sql-ex.ru
Skip Navigation Links  

 

Print  Версия для печати

На главную страницу

Характерные ошибки при решении упражнений. Задача 41

Моисеенко С.И.

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

Еще недавно формулировка этой задачи звучала так:
Найдите названия всех кораблей, спущенных на воду до 1918 г.

Эта задача допускала весьма простое решение:

SELECT name AS shipName
    FROM Ships
    WHERE launched < 1918

Однако, как справедливо заметил Zhekaus, здесь никак не учитываются даты сражений. Действительно, если год спуска на воду корабля неизвестен, и при этом он участвовал в сражении, которое произошло до 1918 года, то такой корабль следует включать в результат. Поскольку в базе данных нет сражений, произошедших ранее 1918 года, то приведенное выше решение будет приниматься системой без учета этого факта.

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

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

Почему? Ответ на этот вопрос опять следует искать в "висящих" головных кораблях. Итак, корабль из Outcomes, имя которого совпадает с именем одного из классов (головной корабль), отсутствует в таблице Ships или присутствует, но с неизвестным годом спуска на воду. Пусть в таблице Ships есть корабль того же класса с известным годом спуска на воду. Если этот год окажется меньше 1941, то головной корабль следует включать в результирующий набор наряду с упомянутым кораблем. Это следует из того факта, что головной корабль - это первый корабль в своем классе и, следовательно, также должен был быть спущен на воду ранее 1941 года.

Есть еще один капкан. Всего лишь год поменять, а сколько интересного можно извлечь. Попробуйте найти его самостоятельно. В противном случае читаем дальше.

Беда с этими головными кораблями! В описании базы данных сказано, что имя классу может давать первый корабль в этом классе, который называется головным, или имя проекта. В последнем случае головного корабля просто не существует. Поэтому когда в задании сказано найти "все корабли…", нельзя рассматривать таблицу Classes в качестве списка головных кораблей.

Вот как иногда неправильно решается вопрос о головных кораблях, спущенных на воду ранее 1941 года:

SELECT class FROM Classes
    WHERE EXISTS (SELECT 1 FROM Ships
    WHERE launched < 1941 and Ships.class = Classes.class)

Итак, головным кораблем является корабль, имя которого совпадает с именем класса. Наконец, о капкане, о котором я говорил выше. Никак не думал, что поставил капкан на себя. Пока я не написал объяснение, которое вы сейчас читаете, мне каждый день приходилось отвечать на несколько писем по этому поводу.

Итак, возможна такая ситуация. Имеется головной корабль с неизвестным годом спуска на воду. Более того, он может участвовать всего в одном сражении, например, в 1945 году. Есть другой корабль этого класса, год спуска на воду тоже неизвестен. Однако если он участвовал в сражении до 1941 года, то нам следует оба эти корабля включить в результирующий набор, т.к. головной корабль (если он есть!!!) должен быть спущен на воду ранее любого другого корабля его класса.

Так что чистая логика, и никаких подвохов.

Приведенные здесь примеры можно выполнить непосредственно на сайте, установив флажок "Без проверки" на странице с упражнениями на SELECT.

Перейти к решению задачи #41

На главную страницу

Print  Версия для печати


Использование любых материалов данного сайта возможно только
при условии обязательного размещения прямой ссылки на сайт
http://www.sqlbooks.ru
на каждой странице, где размещены используемые материалы.

 Начало   Статьи    Книги 
Рейтинг@Mail.ru Rambler's Top100 Alt Упражнения по SQL: обучение, тестирование, сертификация по языку SQL Copyright c 2002-2006. All rights reserved.