with vals (id, color, price) as
(
values
('товар 1', 'белый', 1.45),
('товар 2', 'белый', 1.65),
('товар 3', 'белый', 2.45),
('товар 4', 'чёрный', 1.45),
('товар 5', 'чёрный', 1.65),
('товар 6', 'чёрный', 2.45),
('товар 7', 'белый', 3.95),
('товар 8', 'чёрный', 0.15),
('товар 9', 'белый', 0.95),
('товар 10', 'белый', 0.85),
('товар 11', 'чёрный', 3.55),
('товар 12', 'чёрный', 8.55),
('товар 13', 'белый', 6.1),
('товар 14', 'синий', 3.55),
('товар 15', 'синий', 8.55),
('товар 16', 'синий', 6.1)
)
select id, color, price
from
(
select v.*, row_number() over (partition by color order by price) as rn1
from vals v
) a
order by case when mod(rn1, 3) != 0 then rn1 / 3 else (rn1 / 3) - 1 end, color, price