我使用Postgres数据库.此DB具有一个包含用户的表,该用户具有生日(日期字段).现在我想让所有在即将到来的一周里过生日的用户….
我的第一次尝试:SELECT id FROM public.users WHERE id IN(lange reeks)AND birthdate> NOW()和birthdate<现在()间隔'1周' 但这并没有结果,显然是因为一年之后.我该如何解决这个问题? 有没有人知道PG在29-02生日会发生什么事情?
我们可以使用postgres函数以非常好的方式执行此操作.
假设我们有一个表人,在列dob中有一个出生日期,这是一个日期,我们可以创建一个函数,允许我们将该列索引,而忽略年份. (感谢Zoltán Böszörményi):
CREATE OR REPLACE FUNCTION indexable_month_day(date) RETURNS TEXT as $BODY$ SELECT to_char($1,'MM-DD'); $BODY$language 'sql' IMMUTABLE STRICT; CREATE INDEX person_birthday_idx ON people (indexable_month_day(dob));
现在,我们需要查询表和索引.例如,为了让每个人在任何一年的4月份过生日:
SELECT * FROM people WHERE indexable_month_day(dob) >= '04-01' AND indexable_month_day(dob) < '05-01';
有一个问题:如果我们的开始/结束时段超过一年的边界,我们需要更改查询:
SELECT * FROM people WHERE indexable_month_day(dob) >= '12-29' OR indexable_month_day(dob) < '01-04';
为了确保我们匹配闰日生日,我们需要知道我们是否会向前或向后“移动”它们.就我而言,两天都匹配起来比较简单,所以我的常规查询如下:
SELECT * FROM people WHERE indexable_month_day(dob) > '%(start)%' %(AND|OR)% indexable_month_day(dob) < '%(finish)%';
我有一个django queryset方法,使这更简单:
def birthday_between(self,start,finish): """Return the members of this queryset whose birthdays lie on or between start and finish.""" start = start - datetime.timedelta(1) finish = finish + datetime.timedelta(1) return self.extra(where=["indexable_month_day(dob) < '%(finish)s' %(andor)s indexable_month_day(dob) > %(start)s" % { 'start': start.strftime('%m-%d'),'finish': finish.strftime('%m-%d'),'andor': 'and if start.year == finish.year else 'or' }] def birthday_on(self,date): return self.birthday_between(date,date)
现在,我可以做以下事情:
Person.objects.birthday_on(datetime.date.today())
仅在前一天或仅在后一天匹配闰日生日:您只需将sql测试更改为“> =”或“< =”,而不是调整开始/结束时间python函数.