Ditt första fel var att lagra ett datum som en varchar-kolumn. Du borde inte göra det där.
Den rätta lösningen för ditt problem är att konvertera kolumnen till ett riktigt date
kolumn .
Nu är jag ganska säker på att svaret på det påståendet är "Jag designade inte databasen och jag kan inte ändra den", så här är en lösning:
CAST
och to_char()
är inte oföränderliga eftersom de kan returnera olika värden för samma inmatningsvärde beroende på den aktuella sessionens inställningar.
Om du vet att du har ett konsekvent format för alla värden i tabellen (vilket - om du hade - skulle innebära att du kan konvertera kolumnen till ett riktigt date
kolumn) så kan du skapa din egen funktion som konverterar en varchar till ett datum och markeras som oföränderlig.
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
/
Med den definitionen kan du skapa ett index på uttrycket:
CREATE INDEX date_index ON table_name (fix_bad_datatype(varchar_column));
Men du har att använda exakt det funktionsanropet i din fråga så att Postgres använder det:
select *
from foo
where fix_bad_datatype(varchar_column) < current_date;
Observera att detta tillvägagångssätt kommer att misslyckas om du bara har ett "olagligt" värde i din varchar-kolumn. Den enda vettiga lösningen är för att lagra datum som date
s,