簡體   English   中英

通過jOOQ查找即將到來的生日

[英]Finding upcoming birthdays with 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 )是天數。 您想要的就是將SQL標准INTERVAL YEAR TO MONTH到給定日期。 如果您想添加一個固定的間隔,可以通過使用jOOQ的YearToMonth間隔類型來實現。 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通常是編寫特定於方言的日期時間算術表達式的最佳方法。

解決問題的一種方法是在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()").

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM