Условная / смешанная сортировка Postgres

У меня есть таблица со столбцом временной метки, примерно так:

╔═══════╦════════════╦
║ name  ║ date_time  ║ 
╠═══════╬════════════╬
║  A    ║     100    ║
║  B    ║     110    ║
║  C    ║     120    ║
║  D    ║     140    ║
║  E    ║     180    ║
║  F    ║     190    ║
╚═══════╩════════════╩

Мне нужно вернуть записи, чтобы записи попали в две группы: записи, в которых date_time находится в будущем, являются первой группой, а записи, где date_time находится в прошлом, - второй группой. Записи в будущем необходимо отсортировать в порядке возрастания (т. Е. Ближайшие к настоящему времени идут первыми), а записи в прошлом необходимо отсортировать в порядке убывания.

Мне удалось решить эту проблему, выполнив два отдельных запроса и объединив результаты с помощью union all, но это не очень эффективно, и мне было любопытно узнать, есть ли лучший подход? Может быть, используя условную сортировку по порядку?

Используйте и ORDER BY с предложением CASE в нем.

The Impaler 21.09.2018 15:34
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
2
1
174
2

Ответы 2

В Postgres вы можете сортировать логические значения - значения false идут перед значениями true. Таким образом, вы можете сортировать по двум выражениям - условию, которое проверяет, находится ли запись в прошлом или будущем, и абсолютному расстоянию между ней и текущей временной меткой:

SELECT *
FROM   mytable
ORDER BY date_time < CURRENT_TIMESTAMP, 
         ABS(EXTRACT(EPOCH FROM CURRENT_TIMESTAMP) -
             EXTRACT(EPOCH FROM date_time))

Мне нравится это решение. Это довольно просто и по делу. Голосование за.

The Impaler 21.09.2018 15:40

@TheImpaler current_timestamp - это функция stable, поэтому CTE не нужен. См. postgresql.org/docs/10/static/xfunc-volatility.html

Mureinik 21.09.2018 15:45

Чувак, ты узнаешь что-то новое каждый день: D Не знал о стабильности всех функций даты / времени в PostgreSQL (которые используют время начала транзакции). Спасибо за разъяснения.

The Impaler 21.09.2018 15:49

Я бы сделал это с помощью трех ключей сортировки:

order by (date_time < current_timestamp),
         (case when date_time < current_timestamp then date_time end) desc,
         date_time asc;

Здесь - это рекстестер.

Другие вопросы по теме