If you want any number of offers, then the problem is rather hard. This comes close to what you want:
select (@rn := @rn + 1) id, offers
from (select group_concat(distinct x.offer_id order by x.offer_id) as offers
from tableX x
group by x.order_id
) xx cross join
(select @rn := 0) var
group by offers;
This puts the offers on a single row in a comma delimited list. If you really need them on separate rows, I would then build on this:
select id, substring_index(substring_index(offers, ',', n.n), ',', -1) as offer
from (select (@rn := @rn + 1) id, offers
from (select group_concat(distinct x.offer_id order by x.offer_id) as offers,
count(distinct x.offer_id) as numoffers
from tableX x
group by x.order_id
) xx cross join
(select @rn := 0) var
group by offers
) o join
(select 1 as n union all select 2 as n union all select 3 as n union all select 4 as n
) n
on n.n <= numoffers;
Of course, the n
subquery needs to have at least the maximum number of offers for an order.