我正在尝试转换查找即将到来的生日的现有查询以使用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?我不太关心当前的格式,我只想了解如何获得相同的结果。
答案 0 :(得分:3)
jOOQ的Field.add()
方法受到Oracle对
DATE + NUMBER
...其中NUMBER
(如果Integer
或Double
)是天数。您想要的是相当于在给定日期添加SQL标准INTERVAL YEAR TO MONTH
。如果要添加常量间隔,可以通过使用jOOQ's YearToMonth
interval type来实现。 YearToMonth
类型也会扩展java.lang.Number
,因此也可以直观地与Field.add()
一起使用。
虽然可以通过现有的jOOQ 3.2 API生成这样的Field<YearToMonth>
,但我相信你最好只使用普通的SQL,可能是通过创建一个可重用的方法:
public static <T extends java.util.Date>
Field<T> dateInCurrentYear(Field<T> field) {
return DSL.field("DATE_ADD({0}, INTERVAL YEAR(CURDATE()) - YEAR({0}) YEAR)",
field.getDataType(),
field);
}
这可能是#2727的有用功能添加......
不幸的是,各种SQL方言对日期时间算术的解释很难标准化。我们在那里不断改进,但通常,纯SQL是编写特定于方言的日期时间算术表达式的最佳方式。
答案 1 :(得分:1)
解决问题的一种方法是在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()").