我有以下查询,我需要实现一个Mailer,需要发送给今天生日的所有客户.这种情况每天发生.现在我需要实现的只是选择使用Postgres SQL查询的Birthday客户端,而不是在PHP中过滤它们.
存储在数据库中的日期格式是YYYY-MM-DD,例如.1984年3月13日
我所拥有的是以下查询
SELECT cd.firstname,
cd.surname,
SUBSTRING(cd.birthdate,6),
cd.email
FROM client_contacts AS cd
JOIN clients AS c ON c.id = cd.client_id
WHERE SUBSTRING(birthdate,6) = '07-20';
Run Code Online (Sandbox Code Playgroud)
有没有比我上面做的更好的方法来进行此查询?
Jor*_*dan 11
您可以将where子句设置为:
WHERE
DATE_PART('day', birthdate) = date_part('day', CURRENT_DATE)
AND
DATE_PART('month', birthdate) = date_part('month', CURRENT_DATE)
Run Code Online (Sandbox Code Playgroud)
如果重要,年龄函数将让您解决闰年问题:
where age(cd.birthdate) - (extract(year from age(cd.birthdate)) || ' years')::interval = '0'::interval
Run Code Online (Sandbox Code Playgroud)
如果您想要性能,您实际上可以将上面的任意起点(例如'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);
Run Code Online (Sandbox Code Playgroud)
(请注意,它在技术上是不可变的,因为日期取决于时区.但是创建索引需要不可变部分,如果你没有在整个地方改变时区,那么它是安全的.)
编辑:我刚刚测试了上面的一点,索引建议实际上不适用于feb-29th.2月29日产生1天28天的day_of_birth,虽然正确,但需要添加到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)
Run Code Online (Sandbox Code Playgroud)
因此:
where birthdate(cd.birthdate) = current_date
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4612 次 |
最近记录: |