Упражнение 25

Найдите производителей принтеров, которые производят ПК с наименьшим объемом RAM и с самым быстрым процессором среди всех ПК, имеющих наименьший объем RAM. Вывести: Maker

Ключевой здесь является фраза «имеющих наименьший объем RAM». Она не избыточна, как это может показаться на первый взгляд. Не достаточно найти все модели, имеющие максимальную скорость среди ПК с минимальной RAM.

Поясним сказанное демонстрацией неправильных решений. Для этой задачи их немало накопилось. Вот первый пример.

Решение 1.17.1

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
               );
🚫
[[ error ]]
[[ column ]]
NULL [[ value ]]
  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, например).

  1. Ошибка в определении производителей принтеров
AND EXISTS (SELECT d.model
            FROM Printer d, Product e
            WHERE d.model=e.model
                AND e.maker = c.maker
           )

Мы уже обсуждали этот вопрос здесь.

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

Решение 1.17.2

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
                                              )
                               )
                );
🚫
[[ error ]]
[[ column ]]
NULL [[ value ]]

Вот как определяется здесь максимум по скорости среди моделей с минимальной памятью:

speed = (SELECT MAX(speed)
FROM (SELECT speed
      FROM PC
      WHERE ram = (SELECT MIN(ram)
                   FROM PC
                  )
     ) AS z4
)

Что же осталось. Вернемся к формулировке, в которой требуются «ПК с наименьшим объемом RAM и с самым быстрым процессором среди всех ПК, имеющих наименьший объем RAM». Фактически, здесь содержится два условия:

ПК с наименьшим объемом RAM

и

ПК с самым быстрым процессором среди всех ПК, имеющих наименьший объем RAM

В рассматриваемом решении используется только второе из этих условий, а именно, определяются лишь модели, имеющие скорость, совпадающую с максимальной скоростью для моделей с минимальной памятью.

Поясним на примере. Пусть минимальная память для моделей ПК в БД— 64 Мбайт и имеются следующие модели:

Speedram
60064
600128
45064

Код, используемый для определения искомой скорости,

SELECT MAX(speed)
FROM (SELECT speed
      FROM PC
      WHERE ram = (SELECT MIN(ram)
                   FROM PC
                  )
     ) AS z4;
🚫
[[ error ]]
[[ column ]]
NULL [[ value ]]

даст 600. Действительно, это максимальная скорость для моделей с минимальной (64) памятью. А далее мы отбираем модели с этой скоростью, куда попадает и модель {600, 128}, хотя она и не отвечает условиям задачи. Если производитель этой модели выпускает еще и принтеры (а он выпускает!), да к несчастью еще и не является производителем модели {600, 64}, то получаем «неверно» при проверке запроса.

Правильным выбором будет, естественно, лишь модель {600, 64}. Надеемся, что теперь решить эту задачу не составит труда.

Решить задачу на SQL-EX.RU