В чем разница в запросе?
От: Sharov Россия  
Дата: 04.02.20 12:23
Оценка:
Здравствуйте.

В чем разница в сл. (под)запросах:

Задачка на sql-ex №25

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


Почему "group by having" не подошел?

Заранее благодарю.
Кодом людям нужно помогать!
Re: В чем разница в запросе?
От: Softwarer http://softwarer.ru
Дата: 04.02.20 12:31
Оценка: 10 (1)
Здравствуйте, Sharov, Вы писали:

S> Почему "group by having" не подошел?


Если коротко — потому, что условие, которое ты написал в having, для всех непустых speed тождественно равно true. А если подробнее — то представь, что ты — SQL-сервер, и напиши алгоритм, как ты будешь вычислять результат такого запроса (а не как тебе хотелось бы, чтобы сервер его вычислял).
Re[2]: В чем разница в запросе?
От: Sharov Россия  
Дата: 04.02.20 13:04
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>Если коротко — потому, что условие, которое ты написал в having, для всех непустых speed тождественно равно true. А если подробнее — то представь, что ты — SQL-сервер, и напиши алгоритм, как ты будешь вычислять результат такого запроса (а не как тебе хотелось бы, чтобы сервер его вычислял).


Сначала выбираю модели с min(ram), далее группирую по model, speed и выбираю те model, у которых speed = max(speed).

>что условие, которое ты написал в having, для всех непустых speed тождественно равно true.


А почему он не выбирет только max скорость?
Кодом людям нужно помогать!
Re[3]: В чем разница в запросе?
От: Softwarer http://softwarer.ru
Дата: 04.02.20 13:50
Оценка: 5 (1)
Здравствуйте, Sharov, Вы писали:

S>Сначала выбираю модели с min(ram), далее группирую по model, speed и выбираю те model, у которых speed = max(speed).


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

S>А почему он не выбирет только max скорость?


А кто сказал, что он не выбирает только max скорость? Очень даже выбирает...
Re[4]: В чем разница в запросе?
От: Sharov Россия  
Дата: 04.02.20 14:25
Оценка:
Здравствуйте, 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 или он тут безсмысленен?
Кодом людям нужно помогать!
Re[5]: В чем разница в запросе?
От: Softwarer http://softwarer.ru
Дата: 04.02.20 14:48
Оценка: 10 (1)
Здравствуйте, Sharov, Вы писали:

S>Можно как-то исходный подзапрос переписать через group by или он тут безсмысленен?


Смысл GROUP BY в том, что выборка бьётся на группы, и из каждой группы в результат идёт одна строка. При этом по смыслу операции результирующая строка не присутствует в исходных данных, а получается каким-то расчётом над группой в целом. В данном запросе в результате требуются строки, отобранные из исходной таблицы наложением определённого фильтра. Группировку здесь может быть и можно каким-то боком засунуть, но в целом она не уместна.
Re[5]: В чем разница в запросе?
От: IT Россия linq2db.com
Дата: 04.02.20 14:49
Оценка: 10 (1)
Здравствуйте, Sharov, Вы писали:

S>Можно как-то исходный подзапрос переписать через group by или он тут безсмысленен?


В твоём случае нет. Можно использовать CTE, чтобы не повторять часть запроса дважды.
Если нам не помогут, то мы тоже никого не пощадим.
Re[6]: В чем разница в запросе?
От: Sharov Россия  
Дата: 04.02.20 16:42
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>Смысл GROUP BY в том, что выборка бьётся на группы, и из каждой группы в результат идёт одна строка. П


Т.е. max выбирается из каждой группы, как я выше на примере показал, так?
Кодом людям нужно помогать!
Re: В чем разница в запросе?
От: Igorxz  
Дата: 05.02.20 00:35
Оценка: 5 (1)
а у меня, к примеру, получился сходу вот такой запрос:
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 )
  )
;
Re: В чем разница в запросе?
От: Danchik Украина  
Дата: 12.02.20 18:37
Оценка: 76 (1)
Здравствуйте, Sharov, Вы писали:


S>Задача №25 на sql-ex, если кому интересно:

S>

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
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.