Rozwiązanie bez użycia UNION/CASE
SELECT * FROM posts
ORDER BY
DATE(published_at)=DATE(NOW()) DESC,
DATE(published_at)<DATE(NOW()) DESC,
DATE(published_at)>DATE(NOW()) ASC`
sprawdź, czy to działa. Działa dobrze z danymi stymulowanymi. Możesz zmienić opis na asc zgodnie z wymaganiami sortowania dat przeszłych i przyszłych