如果它的事項,年齡功能將讓您解決閏年問題:
where age(cd.birthdate) - (extract(year from age(cd.birthdate)) || ' years')::interval = '0'::interval
如果你想要表現,你可以用任意的起點(例如, 'epoch'::date
)到一個函數,也和它使用索引:
create or replace function day_of_birth(date)
returns interval
as $$
select age($1, 'epoch'::date)
- (extract(year from age($1, 'epoch'::date)) || ' years')::interval;
$$ language sql immutable strict;
create index on client_contacts(day_of_birth(birthdate));
...
where day_of_birth(cd.birthdate) = day_of_birth(current_date);
(請注意,這不是技術上一成不變的,因爲日期取決於時區,但需要不可改變的部分來創建索引,它是安全的,如果你不更改時區所有的地方)
編輯:我剛剛測試了一下上方,該指數的建議其實並不二月至29日工作。 2月29日產生1天28天的日期,雖然正確,但需要在1月1日之前添加,以產生當年的有效出生日期。
create or replace function birthdate(date)
returns date
as $$
select (date_trunc('year', now()::date)
+ age($1, 'epoch'::date)
- (extract(year from age($1, 'epoch'::date)) || ' years')::interval
)::date;
$$ language sql stable strict;
with dates as (
select d
from unnest('{
2004-02-28,2004-02-29,2004-03-01,
2005-02-28,2005-03-01
}'::date[]) d
)
select d,
day_of_birth(d),
birthdate(d)
from dates;
d | day_of_birth | birthdate
------------+---------------+------------
2004-02-28 | 1 mon 27 days | 2011-02-28
2004-02-29 | 1 mon 28 days | 2011-03-01
2004-03-01 | 2 mons | 2011-03-01
2005-02-28 | 1 mon 27 days | 2011-02-28
2005-03-01 | 2 mons | 2011-03-01
(5 rows)
而且這樣的:
where birthdate(cd.birthdate) = current_date
那去年生的人呢? –
顯然我需要睡覺,而不是回答這個問題。我會編輯。 – Jordan
@jordan - 感謝您的努力,但我們的客戶沒有一天是老;-) – Roland