Примерно так:
select *
from product p1
where (select count(*) from product p2
where p2.product_type=p1.product_type and p2.price<p1.price)<4
order by product_type, product_price;
вложенный запрос ранжирует товары по цене в своем типе (чем больше цена другого <цены этого товара, тем больше номер его ранга; самый дешевый имеет ранг 0), внешний запрос просто выбирает те товары с рангом между 0 и 3. </p>
Поскольку вы написали "заказ по", я понимаю, что вам нужен каждый элемент, а не их совокупность. Следовательно, group by не нужен во внешнем запросе. Если вам нужна только строка с их именами, то идите по этому пути:
select
group_concat(name)
from product p1
where (select count(*) from product p2
where p2.product_type=p1.product_type and p2.price<p1.price)<4
group by product_type;