我正在尝试创建一种方法,该方法将返回任意长度的日期序列,然后将其用于生成按小时/天/月分组的使用情况报告。
这可以针对多个数据库非常重要。我有一个针对单个实现的解决方案,但这相当笨拙。
这是用例:
Table<Record> generateDateSeries(OffsetDateTime minDate, OffsetDateTime maxDate) {
## TODO implement
}
Table<Record> truncatedDateSeries = generateDates(OffsetDateTime.now().minus(Duration.ofDays(7)), OffsetDateTime.now());
// So that it can then be used in a query such as the following
/*
* Get all of the usage with a date range grouped by a date part
*/
db.select(
truncatedDateSeries.field(columnDate).cast(OffsetDateTime.class),
dataTable.field(columnDownload).cast(BigDecimal.class))
.from(truncatedDateSeries)
.leftOuterJoin(dataTable)
.using(field(columnDate)).fetch()
我目前对generateDateSeries
的实现如下:
Table<Record> generateDates(OffsetDateTime minDate, OffsetDateTime maxDate) {
Name cte = name("dateSeries");
Name dateValue = name("dateValue");
return DSL.withRecursive(cte).as(
select(value(minDate).as(field(dateValue)))
.unionAll(
select(
field(dateValue, OffsetDateTime.class).add(1)).from(cte).where(
field(dateValue).add(1).lessThan(maxDate)
)
)
).select().from(cte).asTable();
}
最终,当我们最终运行查询时,我们得到了
ERROR: operator does not exist: timestamp with time zone + integer
SQL state: 42883
Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
Character: 188
足够公平。
但是,即使在看过dateAdd
和timestampAdd
之后,我仍然无法找到一个可行的解决方案,更不用说一个简洁明了的解决方案了。
答案 0 :(得分:0)
对区间算术进行标准化的最简单方法是使用DSL.timestampAdd()
,它与TIMESTAMP
数据类型(即TIMESTAMP WITHOUT TIME ZONE
)一起使用。支持DSL.offsetDateTimeAdd()
is on the roadmap,并且从jOOQ 3.11开始不可用。
话虽如此,对OffsetDateTime
进行标准化将导致自身的困难,因为各种RDBMS对TIMESTAMP WITH TIME ZONE
的含义有不同的理解。