I agree with KM, make the developers do some work--this kind of stuff HAS to be easier to do in procedural code. But if they're all on vacation (like me in 2 hours), this frankenstein query would work. This was done in SQL 2005 using common table expressions, but something similar (if even more awkward) using temp tables would work.
;WITH SourceData (ProductId, EvenOdd)
as (select ProductId, row_number() over (order by ProductId) EvenOdd
from Products)
,OddData (ProductId, OrderNum)
as (select ProductId, row_number() over (order by EvenOdd) OrderNum
from SourceData
where EvenOdd%2 = 1)
,EvenData (ProductId, OrderNum)
as (select ProductId, row_number() over (order by EvenOdd) OrderNum
from SourceData
where EvenOdd%2 = 0)
SELECT od.ProductId, ed.Productid
from OddData od
left outer join EvenData ed
on ed.OrderNum = od.OrderNum
"ProductId" is the column you want to sort. Doesn't matter if there are duplicates or gaps in your sequence. If there's an odd number of items, that last right-hand value will be null. You could even expand this to have more than 2 columns returned.