Ответ 1
Ваша первая ошибка заключалась в том, чтобы сохранить дату в качестве столбца varchar. Вы не должны этого делать.
Правильное исправление для вашей проблемы - преобразовать столбец в реальный столбец date
.
Теперь я уверен, что ответ на этот вопрос: "Я не проектировал базу данных, и я не могу ее изменить", поэтому обходной путь:
CAST
и to_char()
не являются неизменяемыми, потому что они могут возвращать разные значения для одного и того же входного значения в зависимости от текущих настроек сеанса.
Если вы знаете, что у вас есть согласованный формат всех значений в таблице (что - если бы вы имели - означало бы, что вы можете преобразовать столбец в реальный столбец date
), тогда вы можете создать свою собственную функцию, которая преобразует varchar к дате и обозначается как неизменный.
create or replace function fix_bad_datatype(the_date varchar)
returns date
language sql
immutable
as
$body$
select to_date(the_date, 'yyyy-mm-dd');
$body$
ROWS 1
/
С помощью этого определения вы можете создать индекс для выражения:
CREATE INDEX date_index ON table_name (fix_bad_datatype(varchar_column));
Но вы должны использовать именно этот вызов функции в своем запросе, чтобы Postgres его использовал:
select *
from foo
where fix_bad_datatype(varchar_column) < current_date;
Обратите внимание, что этот подход сильно не удастся, если у вас есть только одно "незаконное" значение в столбце varchar. Единственное разумное решение -, чтобы хранить даты как date
s,