用jOOQ找到即将到来的生日

我正在尝试转换查找即将到来的生日的现有查询以使用jOOQ。 我最初的查询 – 使用MySQL,有点简化 – 是

SELECT COUNT(*) FROM people WHERE DATE_ADD(people_dob, INTERVAL YEAR(CURDATE()) - YEAR(people_dob) YEAR) BETWEEN CURDATE() and DATE_ADD( CURDATE(), INTERVAL 7 DAY) 

我试图用jOOQ表达它,但失败了。 我尽可能接近

 context .selectCount() .from(PEOPLE) .where( PEOPLE_DOB.add(year(currentTimestamp()).minus(year(PEOPLE_DOB))) .between(currentTimestamp()).and(currentTimestamp().add(7))); 

不幸的是,这转化为

 select count(*) from `people` where date_add(`people`.`people_dob`, interval (extract(year from current_timestamp()) - extract(year from `people`.`people_dob`)) day) between current_timestamp() and date_add(current_timestamp(), interval 7 day) 

这里打破查询的是[DATE_ADD] [date_add]的expr_unit参数,这是我的原始查询是YEAR ,但是在jOOQ呈现的那个是DAY

如何将此查询翻译成jOOQ? 我不太关心当前的格式,我只是想了解如何获得相同的结果。

jOOQ的Field.add()方法的灵感来自Oracle对其的解释

 DATE + NUMBER 

…其中NUMBER (如果是IntegerDouble Integer数)是天数。 您想要的是相当于在给定日期添加SQL标准INTERVAL YEAR TO MONTH 。 如果要添加常量间隔,可以通过使用jOOQ的YearToMonth间隔类型来实现。 YearToMonth类型还扩展了java.lang.Number ,因此也可以直观地与Field.add()一起使用。

虽然可以通过现有的jOOQ 3.2 API生成这样的Field ,但我相信你最好只使用普通的SQL,可能是通过创建一个可重用的方法:

 public static  Field dateInCurrentYear(Field field) { return DSL.field("DATE_ADD({0}, INTERVAL YEAR(CURDATE()) - YEAR({0}) YEAR)", field.getDataType(), field); } 

这可能是#2727的有用function添加……

不幸的是,各种SQL方言对日期时间算术的解释很难标准化。 我们在那里不断改进,但通常,纯SQL是编写特定于方言的日期时间算术表达式的最佳方式。

解决问题的一种方法是在where子句中使用String。 我在这里写下来是为了完整,但我认为它错过了jOOQ的观点

 context. selectCount(). from(PEOPLE). where("DATE_ADD(people_dob, INTERVAL YEAR(CURDATE()) - YEAR(people_dob) YEAR)" + " BETWEEN DATE_SUB(CURDATE(), INTERVAL 7 DAY) AND CURDATE()"). 
    Interesting Posts