2013-12-20 3 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. Я пишу это здесь для полноты картины, но я думаю, что не попадает в точку 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() вдохновлен интерпретации Oracle о

DATE + NUMBER 

... где NUMBER (если Integer или Double) количество дней. То, что вы хотите, эквивалентно добавлению стандарта 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 - это лучший способ написать диалектические выражения с датами времени.