Lỗi đầu tiên của bạn là lưu ngày tháng dưới dạng cột varchar. Bạn không nên làm điều đó.
Cách khắc phục thích hợp cho sự cố của bạn là chuyển đổi cột thành một date
thực cột .
Bây giờ tôi khá chắc chắn câu trả lời cho câu nói đó là "Tôi không thiết kế cơ sở dữ liệu và tôi không thể thay đổi nó", vì vậy đây là một cách giải quyết:
CAST
và to_char()
không phải là bất biến vì chúng có thể trả về các giá trị khác nhau cho cùng một giá trị đầu vào tùy thuộc vào cài đặt của phiên hiện tại.
Nếu bạn biết rằng bạn có một định dạng nhất quán cho tất cả các giá trị trong bảng (mà - nếu bạn có - có nghĩa là bạn có thể chuyển đổi cột thành một date
thực sự cột) thì bạn có thể tạo hàm của riêng mình để chuyển đổi một varchar thành một ngày tháng và được đánh dấu là không thể thay đổi.
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
/
Với định nghĩa đó, bạn có thể tạo chỉ mục trên biểu thức:
CREATE INDEX date_index ON table_name (fix_bad_datatype(varchar_column));
Nhưng bạn có sử dụng chính xác lệnh gọi hàm đó trong truy vấn của bạn để Postgres sử dụng nó:
select *
from foo
where fix_bad_datatype(varchar_column) < current_date;
Lưu ý rằng cách tiếp cận này sẽ thất bại nặng nề nếu bạn chỉ có một giá trị "bất hợp pháp" trong cột varchar của mình. Giải pháp hợp lý duy nhất là để lưu trữ ngày dưới dạng date
s,