PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

PostgreSQL crea l'indice sul cast dalla stringa alla data

Il tuo primo errore è stato quello di memorizzare una data come colonna varchar. Non dovresti farlo.

La soluzione corretta per il tuo problema consiste nel convertire la colonna in una vera date colonna .

Ora sono abbastanza sicuro che la risposta a questa affermazione sia "Non ho progettato il database e non posso cambiarlo", quindi ecco una soluzione alternativa:

CAST e to_char() non sono immutabili perché possono restituire valori diversi per lo stesso valore di input a seconda delle impostazioni della sessione corrente.

Se sai di avere un formato coerente di tutti i valori nella tabella (che - se lo avessi - significherebbe che puoi convertire la colonna in una vera date colonna) quindi puoi creare la tua funzione che converte un varchar in una data ed è contrassegnata come immutabile.

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
/

Con quella definizione puoi creare un indice sull'espressione:

CREATE INDEX date_index ON table_name (fix_bad_datatype(varchar_column));

Ma tu hai per usare esattamente quella chiamata di funzione nella tua query in modo che Postgres la usi:

select *
from foo
where fix_bad_datatype(varchar_column) < current_date;

Nota che questo approccio fallirà gravemente se hai solo un valore "illegale" nella tua colonna varchar. L'unica soluzione sensata è per memorizzare le date come date s,