Для этого вы можете использовать оконные функции:
order by row_number() over (partition by product_id order by id)
Нет необходимости помещать это в select
. Вы также можете сделать это, используя подзапрос в более старых версиях:
order by (select count(*)
from item_possession t2
where t2.product_id = t.product_id and t2.id <= t.id
)
В качестве альтернативы, вы можете использовать переменные - что требует сортировки дважды:
select ip.*
from (select ip.*,
(@rn := if(@p = ip.product_id, @rn + 1,
if(@p := ip.product_id, 1, 1)
)
) as rn
from (select ip.* from item_possession ip order by ip.product_id, ip.id
) ip cross join
(select @p := -1, @rn := 0) params
) ip
order by rn, id;