2017-01-12 10 views
2

Ищу диалект-независимый способ вернуть сумму интервалов длительности между двумя полями TIMESTAMP, используя отборный как:Извлечение суммы интервалов в JOOQ

DSL.sum(DSL.timestampDiff(MY_TABLE.START, MY_TABLE.END)) 

В JOOQ, sum(...) возвращает Field<BigDecimal> , Это происходит для работы в HSQLDB, поскольку для INTERVAL используется миллисекундное представление. Однако в PostgreSQL этот запрос падает, поскольку автоматическое преобразование из собственного типа INTERVAL в BigDecimal невозможно.

Теперь я ищу кросс-платформенный способ в JOOQ для преобразования INTERVAL в миллионы секунд, поэтому я могу суммировать эти числа с числовым значением.

Любые предложения? (Или, возможно, есть более элегантный способ решить эту головоломку?)

ответ

3

Это, вероятно, ошибка в jOOQ (#5785).

В качестве обходного пути, вы можете реализовать свою собственную функцию суммы, как это:

public static Field<BigDecimal> sumTimestampDiff(
    final Field<Timestamp> start, 
    final Field<Timestamp> end 
) { 
    return new CustomField<BigDecimal>("sum", SQLDataType.NUMERIC) { 
     @Override 
     public void accept(Context<?> ctx) { 
      switch (ctx.family()) { 
       case HSQLDB: 
        ctx.visit(sum(timestampDiff(start, end))); 
        break; 
       case POSTGRES: 
        ctx.visit(sql("sum(1000 * extract('epoch' from ({0} - {1})))", 
            start, end)); 
        break; 
      } 
     } 
    }; 
} 

Я использую the extract() expression from Evan's answer here.

выше фрагмент кода предполагает, что вы имеете статический импорт:

import static org.jooq.impl.DSL.*; 

More info about CustomField here.

+0

Я бы не сделал этого ни в одном из моих кодов. Я бы сохранил интервалы, как интервалы, и хотел бы получить интервал. Или выполняйте мои операции в БД, где интервалы значительны и обрабатываются должным образом. Но я понятия не имею, как он использует jooq. Тем не менее, рекомендуется включить его в свой язык. –

+0

@EvanCarroll: Я знаю, что вы имеете в виду, но если вы хотите быть агностиком поставщика баз данных, иногда вам приходится работать с ограничениями/несовместимостью. –

+0

Я действительно искал способ JOOQ обрабатывать интервалы в нейтральной платформе. Для меня это включает как встроенное (SQL) преобразование в количество определенных единиц времени, так и получение результата интервала запроса как некоторого типа интервала (например, Java 8 Duration). @LukasEder: Спасибо, что зарегистрировали эту проблему как ошибку. – Timo

1

От the lists

select extract ('epoch' from '5 days 5 hours'::interval); 
+0

Хотя это правильное (и общеизвестное) решение PostgreSQL, это не синтаксис JOOQ. – Timo

Смежные вопросы