На главную страницу
Характерные ошибки при решении упражнений.
Задача 25
Моисеенко С.И.
Найдите производителей принтеров, которые производят ПК с наименьшим объемом RAM
и с самым быстрым процессором среди всех ПК, имеющих наименьший объем RAM.
Вывести: Maker.
Ключевой здесь является фраза "имеющих наименьший объем RAM". Она не избыточна,
как это может показаться на первый взгляд. Не достаточно найти все модели,
имеющие максимальную скорость среди ПК с минимальной RAM.
Поясню сказанное демонстрацией неправильных решений. Для этой задачи их немало
накопилось :-). Вот первый пример:
SELECT c.maker FROM Product c,
(SELECT b.model, MAX(b.speed) speed
FROM Pc b
WHERE b.ram IN (SELECT
MIN(a.ram) FROM Pc a)
GROUP BY b.model) t
WHERE c.model=t.model AND EXISTS
(SELECT d.model FROM Printer d, Product e
WHERE d.model=e.model AND e.maker = c.maker)
1. Ошибка в подзапросе
(SELECT b.model, MAX(b.speed) speed
FROM Pc b
WHERE b.ram IN (SELECT MIN(a.ram) FROM Pc a)
GROUP BY b.model) t
Здесь выбираются модели ПК с минимальной памятью, а для каждой такой модели
определяется ПК с максимальной скоростью. Ошибка состоит в том, что
максимальную скорость нужно определять по всем ПК с минимальной памятью, а не
по каждой модели. Кроме того, если у производителя будет две модели с
минимальной памятью, то он дважды попадет в результирующий набор, т.к. в
запросе отсутствует устранение дубликатов (DISTINCT, например).
2. Ошибка в определении производителей принтеров
EXISTS (SELECT d.model FROM Printer d, Product e
WHERE d.model=e.model AND e.maker = c.maker)
Здесь определяется наличие у производителя ПК моделей принтеров в таблице
Printer. В задании говорится о том, что искомый производитель выпускает также и
принтеры, но ничего не говорится о наличии моделей в таблице Printer. Т.е. если
в таблице Product имеется производитель принтеров, моделей которого нет в
таблице Printer, то рассматриваемый запрос проигнорирует его, хотя он и
отвечает условиям задачи.
Однако мы еще не выявили главной ошибки решения, которую лучше проанализировать,
устранив предыдущие:
SELECT DISTINCT maker
FROM Product
WHERE type = 'printer' AND maker IN
(
SELECT maker FROM Product WHERE
model IN (
SELECT
model FROM Pc
WHERE
speed = (SELECT MAX(speed) FROM
(SELECT
speed FROM Pc WHERE
ram = (SELECT MIN(ram) FROM
Pc)) AS z4)
)
)
В этом решении устранены дубликаты, правильно определены производители
принтеров, а также находится глобальный максимум по скорости среди моделей с
минимальной памятью:
WHERE speed = (SELECT MAX(speed) FROM
(SELECT speed FROM Pc WHERE
ram = (SELECT MIN(ram) FROM
Pc)) AS z4)
Что же осталось. Вспомним фразу, упомянутую в начале главы: "имеющих наименьший
объем RAM". В данном решении мы определяем лишь модели, имеющие скорость,
совпадающую с максимальной скоростью для моделей с минимальной памятью. Поясню
на примере. Пусть минимальная память для компьютеров в БД - 64 и имеются
следующие ПК:
speed |
ram
|
600 |
64 |
600 |
128 |
450 |
64 |
Код, используемый для определения искомой скорости
SELECT MAX(speed) FROM
(SELECT speed FROM Pc WHERE
ram = (SELECT MIN(ram) FROM
Pc)) AS z4
даст 600. Действительно, это максимальная скорость для моделей с минимальной
(64) памятью. А далее мы отбираем модели с этой скоростью, куда попадает и
модель {600, 128}, хотя она и не отвечает условиям задачи. Если производитель
этой модели выпускает еще и принтеры (а он выпускает!), да не является
производителем модели {600, 64}, то получаем "неверно" при проверке запроса.
Правильным выбором будет, естественно, лишь модель {600, 64}. Надеюсь, что
теперь решить эту задачу не составит труда :-).
Приведенные здесь примеры можно выполнить непосредственно на сайте, установив
флажок "Без проверки" на странице с упражнениями
на SELECT.
Перейти к
решению задачи #25
На главную страницу