SELECT distinct model
FROM pc
WHERE ram = (
SELECT MIN(ram)
FROM pc
)
AND speed = (
SELECT MAX(speed)
FROM pc
WHERE ram = (SELECT MIN(ram) FROM pc )
)
и
select distinct model
from PC
where ram =(select min(ram) from PC)
group by model,speed
having speed = max(speed)
Задача №25 на sql-ex, если кому интересно:
Найдите производителей принтеров, которые производят ПК с наименьшим объемом RAM и с самым быстрым процессором среди всех ПК, имеющих наименьший объем RAM. Вывести: Maker
Здравствуйте, Sharov, Вы писали:
S> Почему "group by having" не подошел?
Если коротко — потому, что условие, которое ты написал в having, для всех непустых speed тождественно равно true. А если подробнее — то представь, что ты — SQL-сервер, и напиши алгоритм, как ты будешь вычислять результат такого запроса (а не как тебе хотелось бы, чтобы сервер его вычислял).
Здравствуйте, Softwarer, Вы писали:
S>Если коротко — потому, что условие, которое ты написал в having, для всех непустых speed тождественно равно true. А если подробнее — то представь, что ты — SQL-сервер, и напиши алгоритм, как ты будешь вычислять результат такого запроса (а не как тебе хотелось бы, чтобы сервер его вычислял).
Сначала выбираю модели с min(ram), далее группирую по model, speed и выбираю те model, у которых speed = max(speed).
>что условие, которое ты написал в having, для всех непустых speed тождественно равно true.
Здравствуйте, Sharov, Вы писали:
S>Сначала выбираю модели с min(ram), далее группирую по model, speed и выбираю те model, у которых speed = max(speed).
Верно. А теперь возьми набор данных из нескольких строк и аккуратно так и сделай. Первый шаг можно отбросить — скажем, предположить, что у всех объём памяти одинаковый — а вот следующие аккуратно выполнить именно так, как написано.
S>А почему он не выбирет только max скорость?
А кто сказал, что он не выбирает только max скорость? Очень даже выбирает...
Здравствуйте, Softwarer, Вы писали:
S>Здравствуйте, Sharov, Вы писали:
S>>Сначала выбираю модели с min(ram), далее группирую по model, speed и выбираю те model, у которых speed = max(speed).
S>Верно. А теперь возьми набор данных из нескольких строк и аккуратно так и сделай. Первый шаг можно отбросить — скажем, предположить, что у всех объём памяти одинаковый — а вот следующие аккуратно выполнить именно так, как написано.
Аааа, понял где ошибка:
1,10 (max(speed) == 10)
2,10
3,20 (max(speed) == 20)
4,20
max(speed) для каждой группы будет разная и соотв. выражение speed==max(speed) есть тождество, т.е. true.
Т.е. правильно я понимаю, что having тут вообще получается не нужен?
Можно как-то исходный подзапрос переписать через group by или он тут безсмысленен?
Здравствуйте, Sharov, Вы писали:
S>Можно как-то исходный подзапрос переписать через group by или он тут безсмысленен?
Смысл GROUP BY в том, что выборка бьётся на группы, и из каждой группы в результат идёт одна строка. При этом по смыслу операции результирующая строка не присутствует в исходных данных, а получается каким-то расчётом над группой в целом. В данном запросе в результате требуются строки, отобранные из исходной таблицы наложением определённого фильтра. Группировку здесь может быть и можно каким-то боком засунуть, но в целом она не уместна.
а у меня, к примеру, получился сходу вот такой запрос:
select distinct d.*
from (
select max_speed = max(b.Speed), a.min_ram
from (
select min_ram = min(Ram)
from pc
) a
join pc b on a.min_ram = b.Ram
group by a.min_ram
) c
join pc d on c.max_speed = d.Speed
and c.min_ram = d.Ram
;
план выполняния запроса (sql-server'ный) показывается побыстрее, чем этот:
SELECT distinct model
FROM pc
WHERE ram = (
SELECT MIN(ram)
FROM pc
)
AND speed = (
SELECT MAX(speed)
FROM pc
WHERE ram = (SELECT MIN(ram) FROM pc )
)
;
S>Найдите производителей принтеров, которые производят ПК с наименьшим объемом RAM и с самым быстрым процессором среди всех ПК, имеющих наименьший объем RAM. Вывести: Maker
S> Почему "group by having" не подошел?
S>Заранее благодарю.
Попробуем включить тяжелую артиллерию, чесно план не проверял и не тестировал, но выглядит оно бодрее
select s.Maker
from
(
select
Maker,
DENSE_RANK() OVER (ORDER BY ram, speed DESC) model_rank
from pc
) s
where s.model_rank = 1