给出生日期如何计算下一个生日?

ghi*_*man 7 postgresql

在Postgres数据库中给出此模式:

CREATE TABLE person (
    id serial PRIMARY KEY,
    name text,
    birth_date date,
);
Run Code Online (Sandbox Code Playgroud)

我如何在今天之后查询表格以获取每个人下一个生日的日期?

例如,如果鲍勃birth_date是2000-06-01,那么他的下一个生日将是2016-06-01.

注意:我不是在寻找birth_date+一个预定义的interval,而是一个人出生的下一个周年纪念日.

我在Python中编写了等价物:

def next_birthday(self):
    today = datetime.date.today()
    next_birthday = self.birth_date.replace(year=today.year)
    if next_birthday < today:
        next_birthday = next_birthday.replace(year=today.year + 1)
    return next_birthday
Run Code Online (Sandbox Code Playgroud)

但是我想看看Postgres能否以更高效的方式做到这一点.

a_h*_*ame 6

select birth_date,
       cast(birth_date + ((extract(year from age(birth_date)) + 1) * interval '1' year) as date) as next_birthday
from person
where name = 'Bob'
Run Code Online (Sandbox Code Playgroud)

表达式(extract(year from age(birth_date)) + 1) * interval '1' year计算(完整)年份下一个生日的年龄.将其添加到出生日期时,这将给下一个生日.

为了获得真正的date回报,必须使用强制转换,因为date + interval返回时间戳(包括时间).

如果你删除where条件,你将获得所有"下一个"生日.

您还可以使用以下内容获取即将到来的30天即将到来的生日列表:

select next_birthday,
       next_birthday - current_date as days_until_next
from (
  select birth_date,
         cast(birth_date + ((extract(year from age(birth_date)) + 1) * interval '1' year) as date) as next_birthday
  from person
) as upcoming
where upcoming.next_birthday <= current_date + 30
order by next_birthday;
Run Code Online (Sandbox Code Playgroud)