Много способов.
Использование имени столбца ts в моих примерах. дата для столбца timestamp
может ввести в заблуждение.
1.
Трансляция на date
. (Здесь нам нужен тип date
. В других выражениях date_trunc()
точно так же.). Затем добавьте 1
(integer
) перед вычитанием интервала 1 second
:
SELECT ts::date + 1 - interval '1 sec' AS last_sec_of_day
2.
Добавьте одиночный интервал '1 day - 1 sec'
. Нет необходимости в двух операциях, Postgres интервальный ввод позволяет одно выражение.
SELECT ts::date + interval '1 day - 1 sec' AS last_sec_of_day
3.
Еще проще, добавьте к дате желаемую временную составляющую:
SELECT ts::date + time '23:59:59' AS last_sec_of_day
4.
Однако xxxx-xx-xx 23:59:59
— это не конец дня. Postgres timestamp
тип данных (в настоящее время, но вряд ли изменится) хранит значения с микросекундным разрешением.
Самая поздняя возможная отметка времени для дня: xxxx-xx-xx 23:59:59.999999
:
SELECT ts::date + interval '1 day - 1 microsecond' AS last_ts_of_day
5.
Эквивалент:
SELECT ts::date + time '23:59:59.999999' AS last_ts_of_day -- or interval
Это последнее выражение должно быть самым быстрым, кроме правильного.
6.
Однако лучше всего использовать начало следующего дня в качестве исключающей верхней границы, что не зависит от деталей реализации и его еще проще сгенерировать:
SELECT ts::date + 1 AS next_day
7.
Фактическая первая временная метка следующего дня:
SELECT date_trunc('day', ts) + interval '1 day' AS next_day_1st_ts
Все работает в любой версии, начиная хотя бы с Postgres 8.4. Демо в Postgres 13:
db‹›fiddle здесь
person
Erwin Brandstetter
schedule
01.01.2015