在JOOQ

时间:2017-01-12 16:58:38

标签: postgresql hsqldb jooq

我正在寻找一种与方言无关的方法来返回两个TIMESTAMP字段之间的间隔持续时间之和,使用如下选择:

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

在JOOQ中,sum(...)会返回Field<BigDecimal>。这恰好在HSQLDB中起作用,因为它使用INTERVAL的毫秒表示。但是,在PostgreSQL中,此查询崩溃,因为没有从本机INTERVAL类型到BigDecimal的自动转换。

我现在正在寻找JOOQ中的跨平台方式将INTERVAL转换为(毫秒)秒,因此我可以将这些数字加总为数值。

有什么建议吗? (或者也许有更优雅的方法来解决这个难题?)

2 个答案:

答案 0 :(得分:3)

这可能是jOOQ中的一个错误(#5785)。

作为一种解决方法,您可以像这样实现自己的sum函数:

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

答案 1 :(得分:1)

来自the lists

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