Придерживаясь вашего дизайна
Предполагается формат ISO для 'somedateliteral'
.
Поскольку это должен быть литерал временной метки, я назову его 'timestamp_literal'
.
SELECT *, created_date + make_interval(secs => created_time) AS created_at
FROM mycustomers
WHERE (created_date, created_time)
> (date 'timestamp_literal', EXTRACT(epoch FROM time 'timestamp_literal')::int);
date 'timestamp_literal'
и time 'timestamp_literal'
берут соответствующую часть даты / времени из литерала. (Последний прерывается, если нет временной части, тогда как первый, очевидно, работает и с литералом даты.)
Почему?
Чтобы сделать его «саргируемым». См .:
В отличие от решений, вычисляющих метку времени на лету ¹, этот запрос может используйте базовый c многоколоночный индекс :
CREATE INDEX multicolumn_created ON mycustomers (created_date, created_time);
(¹ Вы могли бы создать соответствующий индекс выражения, чтобы он работал. ..)
Postgres может идеально использовать этот индекс с сравнение значений ROW . (В прошлый раз, когда я посмотрел, MySQL не смог этого сделать.) См.:
Правильное исправление
Обычно временные метки хранятся как date
+ integer
это ошибка дизайна без преимуществ. Вместо этого используйте timestamp
. Вы можете переключиться на обычно предпочитаемый timestamptz
, находясь на нем. См .:
В других ответах уже предоставлены выражения для преобразования (date, integer)
в timestamp
- который вы можете использовать для исправления вашей таблицы:
BEGIN;
-- drop all depending objects: indexes, views, ...
ALTER TABLE mycustomers
ALTER created_date TYPE timestamp
USING (created_date + make_interval(secs => created_time))
, DROP COLUMN created_time;
ALTER TABLE mycustomers RENAME created_date TO created_at; -- or whatever
-- recreate all depending objects: indexes, views, ...
COMMIT;
Очевидно, принять все запросы с использованием этих столбцов. Запрос просто выглядит следующим образом:
SELECT * FROM mycustomers WHERE created_at > 'somedateliteral';
db <> fiddle здесь