首页 > 解决方案 > 如何在 jOOQ 查询中使用 Postgres 的 to_char?

问题描述

我正在尝试将以下 PostgreSQL 查询转换为 jOOQ:

SELECT count(*), to_char(created_date, 'YYYY-MM-DD') as year_month_date
  FROM log
  GROUP BY year_month_date
  ORDER BY year_month_date

我所拥有的是:

jooq.select(
    DSL.count(),
    DSL.field("to_char(created_date, 'YYYY-MM-DD') as year_month_date")
  )
  .from(LOG)
  .groupBy(DSL.field("year_month_date"))
  .orderBy(DSL.field("year_month_date"))
  .fetch();

有没有办法使用 jOOQ 的流畅 API,所以我不必使用字符串?

标签: javasqljooq

解决方案


使用TO_CHAR()

有一个待处理的功能请求来添加对供应商特定to_char()功能的支持:https ://github.com/jOOQ/jOOQ/issues/8381

为了标准化这样的功能,需要做更多的研究以确保我们可以涵盖每个供应商在这里实现的所有内容,因为不幸的是格式化逻辑是特定于供应商的,并且是字符串类型的。

因此,如果您想使用to_char(),目前,您将不得不求助于使用普通 SQL 模板,您已经这样做了。您显然可以以可重用的形式将此实用程序分解出来,例如:

public static Field<String> toChar(Field<?> date, String format) {
    return DSL.field("to_char({0}, {1})", SQLDataType.VARCHAR, date, DSL.inline(format));
}

截断日期

当然,在您的特定查询中,您也可以求助于使用标准 SQL 功能,例如CAST(). 我认为您要做的是从您的timestamportimestamptz列中截断时间信息,因此您可以这样做:

SELECT count(*), CAST (created_date AS DATE) d
  FROM log
  GROUP BY d
  ORDER BY d

或使用 jOOQ:

Field<Date> d = LOG.CREATED_DATE.cast(SQLDataType.DATE);

jooq.select(count(), d)
    .from(LOG)
    .groupBy(d)
    .orderBy(d)
    .fetch();

推荐阅读