Упражнение 10

Найдите модели принтеров, имеющих самую высокую цену. Вывести: model, price

Задача обычно не вызывает затруднений, однако, иногда встречаются решения подобные следующему:

SELECT model, MAX(DISTINCT price)
FROM Printer
GROUP BY model;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

Понятно естественное желание решить задачу без подзапросов. Если бы требовалось вывести только максимальную цену, то тогда группировка была бы не нужна, так как максимум находился бы по всему набору принтеров:

SELECT MAX(price)
FROM Printer;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

Однако в задаче требуется вывести еще и номер (номера) модели, имеющей максимальную цену. Поскольку мы не можем в предложении SELECT использовать агрегатные значения наряду с детализированными (если не использовать группировку по детализированным значениям), то в результате и получаем представленное выше неправильное решение с группировкой по модели. Это решение дает максимальную цену по каждой модели, нам же нужно получить модели, которые имеют абсолютную (по всему набору принтеров) максимальную цену.

Замечание

Новые возможности SQL позволяют выводить агрегатные значения наряду с детализированными с помощью оконных функций. Однако не все сразу.

Итак, приходится использовать подзапрос, в котором вычисляется максимальная цена:

SELECT model, price
FROM Printer
WHERE price = (SELECT MAX(price)
               FROM Printer
               );
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

При этом подзапрос может вводиться не только с простым оператором сравнения («=»), но и с предложением IN или >= ALL.

Подзапрос можно использовать и в предложении FROM:

SELECT model, price
FROM Printer pr, (SELECT MAX(price) AS maxprice
                  FROM Printer
                  ) AS mp
WHERE price = mp.maxprice;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

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

И все же, можно ли решить задачу без подзапроса?

ПиР

Решить упражнение на SQL-EX.RU