How can I order the results from a DISTINCT ON query
Wrapping the query in a derived table is the obvious way to solve this:

SELECT *
FROM
    ( SELECT DISTINCT ON (item_id)
             item_id, data, timestamp, sort_order, ... 
        FROM [this table]
       WHERE group_id = [some value]
         AND timestamp &lt; [some value]
    ORDER BY item_id, timestamp DESC
   ) AS t
ORDER BY sort_order ;


If your original query is efficient and doesn't return too many rows, the additional sort will not add much cost to the query.



Besides DISTINCT ON, there are a few other methods that are often more efficient in this type of "greatest-n-pre-group" queries - but efficiency depends on many parameters, like targeted indexes and distribution of values (how many distinct item_id in the table, how many rows per item_id), Postgres version, etc. 

Most notable method is using LATERAL subqueries. See these excellent answers by Erwin Brandstetter:


Optimize GROUP BY query to retrieve latest record per user
Optimize groupwise maximum query
Select first row in each GROUP BY group?
Query last N related rows per row
Optimise a LATERAL JOIN query on a big table