2013-12-20 32 views
2

我想转换现有的查询,寻找即将到来的生日使用jOOQ。我原来的查询 - 使用MySQL,有点简单化 - 是寻找即将到来的生日与jOOQ

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) 

什么打破了查询这里是expr_unit论据[DATE_ADD] [DATE_ADD],这是我原来的查询是YEAR,但在jOOQ呈现的那个是DAY

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

回答

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()"). 
3

jOOQ的Field.add()方法是通过

DATE + NUMBER 

... Oracle的解释的启发,其中NUMBER(如果IntegerDouble)是多少天。你想要的是相当于将SQL标准INTERVAL YEAR TO MONTH添加到给定的日期。如果你想添加一个固定的时间间隔,可以通过使用jOOQ's YearToMonth interval type来实现。 YearToMonth类型也延伸java.lang.Number,因此可以直观地与Field.add()一起使用。

虽然有可能产生这样的Field<YearToMonth>通过现有jOOQ 3.2 API,我相信你会被关闭,只是采取简单的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是编写特定方言日期时间算术表达式的最佳方式。

相关问题