【问题标题】:Creating a cross target date series with JOOQ使用 JOOQ 创建跨目标日期系列
【发布时间】:2019-08-07 00:44:26
【问题描述】:

我正在尝试创建一种方法,该方法将返回任意长度的日期系列,然后可用于生成按小时/天/月分组的使用情况报告。

这很重要,它可以针对多个数据库。我有一个单独实现的解决方案,但它相当笨拙。

这是用例:


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 之后,我也无法找到一个可行的解决方案,更不用说一个清晰简洁的解决方案了。

【问题讨论】:

  • 虽然可以通过 jOOQ 对其进行标准化,但出于性能原因,我建议您使用供应商特定的扩展。在大多数 RDBMS 中,使用递归 CTE 可能不会在这里给您快速的结果。由于您似乎是从 PostgreSQL 开始的,我建议在那里使用generate_series()。

标签: java sql jooq


【解决方案1】:

标准化区间算术的最简单方法是使用DSL.timestampAdd(),它适用于TIMESTAMP 数据类型(即TIMESTAMP WITHOUT TIME ZONE)。支持DSL.offsetDateTimeAdd() is on the roadmap,从 jOOQ 3.11 起尚不可用。

话虽如此,对OffsetDateTime 进行标准化也会带来困难,因为不同的RDBMS 对TIMESTAMP WITH TIME ZONE 的含义有不同的理解。

【讨论】:

    猜你喜欢
    • 2021-03-25
    • 2017-02-23
    • 2021-01-01
    • 1970-01-01
    • 2017-12-13
    • 2019-12-01
    • 2014-06-26
    • 1970-01-01
    • 2020-05-29
    相关资源
    最近更新 更多