Vaší první chybou bylo uložit datum jako sloupec varchar. Neměl bys to dělat.
Správnou opravou vašeho problému je převést sloupec na skutečné date
sloupec .
Nyní jsem si docela jistý, že odpověď na toto prohlášení je „Nenavrhl jsem databázi a nemohu ji změnit“, takže zde je řešení:
CAST
a to_char()
nejsou neměnné, protože mohou vrátit různé hodnoty pro stejnou vstupní hodnotu v závislosti na nastavení aktuální relace.
Pokud víte, že máte konzistentní formát všech hodnot v tabulce (což – pokud ano – znamenalo by to, že můžete sloupec převést na skutečné date
sloupec), pak si můžete vytvořit vlastní funkci, která převede varchar na datum a je označena jako neměnná.
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
/
Pomocí této definice můžete vytvořit index pro výraz:
CREATE INDEX date_index ON table_name (fix_bad_datatype(varchar_column));
Ale máte použít přesně toto volání funkce ve svém dotazu, aby ho Postgres použil:
select *
from foo
where fix_bad_datatype(varchar_column) < current_date;
Všimněte si, že tento přístup selže, pokud máte ve sloupci varchar pouze jednu "nelegální" hodnotu. Jediné rozumné řešeníje ukládat data jako date
s,