На главную страницу
Характерные ошибки при решении упражнений.
Задача 37
Моисеенко С.И.
Найдите классы, в которые входит только один корабль из базы данных (учесть также
корабли в Outcomes).
Вот один из запросов, которые отвергает система проверки:
SELECT class
FROM ships
GROUP BY class
HAVING COUNT(name) = 1
UNION
SELECT class
FROM classes c, outcomes o
WHERE c.class = o.ship AND
NOT EXISTS (SELECT 'x'
FROM ships s
WHERE o.ship = s.class);
Первый запрос в объединении подсчитывает корабли каждого класса из таблицы
Ships, оставляя в результирующем наборе только те классы, которые имеют только
один корабль. Второй запрос определяет классы, у которых головной корабль
находится в таблице Outcomes при условии, что кораблей такого класса нет в
таблице Ships.
Рассмотрим следующий пример данных, для которых этот запрос будет давать
неправильный результат.
Каждый, кто решал задачи по этой схеме данных ("Корабли"), знает, что такое
Бисмарк. Это головной корабль, которого нет в таблице Ships. Теперь представим
себе, что один другой корабль класса Бисмарк имеется в таблице Ships, скажем,
Терплиц.
Тогда первый запрос вернет класс Бисмарк, т.к. в таблице Ships имеется один
корабль этого класса. Второй запрос класс Бисмарк не вернет, т.к. предикат:
NOT EXISTS (SELECT 'x'
FROM ships s
WHERE o.ship = s.class);
для корабля Бисмарк в таблице Outcomes будет оценен как FALSE. В результате
объединения этих запросов получим класс Бисмарк в выходных данных всего
запроса. Всякому, кто внимательно следил за ходом рассуждений, понятно, что в
базе данных имеется ДВА корабля класса Бисмарк. Т.е. этот класс не должен
присутствовать в результатах выполнения запроса.
Приведя на нашем форуме рассматриваемый запрос, ivc_mayak попросил предоставить
данные, на которых он даст неверный результат. Пожалуйста,
INSERT INTO Ships VALUES('Terplits', 'Bismarck', 1940)
Перейти к
решению задачи #37
На главную страницу