用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
(如果是Integer
或Double
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()").