如何在 Jooq 中按月和年将毫秒翻译成日期和分组?
Posted
技术标签:
【中文标题】如何在 Jooq 中按月和年将毫秒翻译成日期和分组?【英文标题】:How to translate millis to date and group by month and year in Jooq? 【发布时间】:2020-07-05 05:56:55 【问题描述】:我有以下按预期工作的 SQL:
select YEAR(CONVERT_TZ(FROM_UNIXTIME(creation_date / 1000), @@session.time_zone, "Europe/Berlin")) as year,
MONTH(CONVERT_TZ(FROM_UNIXTIME(creation_date / 1000), @@session.time_zone, "Europe/Berlin")) as month,
sum(value)
from transaction
GROUP BY year, month;
我正在尝试在 Jooq 中重新创建这些 SQL,但我不知道如何根据数据库中 creation_date
的毫秒数创建一个 Date 对象。
dsl.select(DSL.month(DSL.date(TRANSACTION.CREATION_DATE)), // This does not work
DSL.year(DSL.date(TRANSACTION.CREATION_DATE)), // This does not work
DSL.sum(TRANSACTION.VALUE))
.from(TRANSACTION)
.groupBy(???); // How to group by month and year?
【问题讨论】:
【参考方案1】:编写 SQL 时常见的混淆GROUP BY
是the logical order of SQL operations。虽然在语法上,SELECT
似乎出现在GROUP BY
之前,但从逻辑上讲,顺序是相反的。这意味着您不能真正从GROUP BY
子句引用SELECT
子句中的列。
一些方言可能“为了方便”实现了异常,但这通常很令人困惑。我建议不要这样做。
但是要解决你的问题:
产生你想产生的 SQL
在原始 SQL 查询中,您为两个表达式(AS year
和 AS month
)使用了别名,而在 jOOQ 查询中却没有。我建议您也使用别名,并将列表达式分配给局部变量以便在 groupBy()
子句中重用:
Field<?> month = DSL.month(DSL.date(TRANSACTION.CREATION_DATE)).as("month");
Field<?> year = DSL.year(DSL.date(TRANSACTION.CREATION_DATE)).as("year");
dsl.select(month, year, DSL.sum(TRANSACTION.VALUE))
.from(TRANSACTION)
.groupBy(month, year)
.fetch();
别名列在SELECT
子句中生成完整声明,但仅在所有其他子句中生成别名,因此这正是您想要的:
SELECT
month(date(transaction.creation_date)) as month,
year(date(transaction.creation_date)) as year
sum(transaction.value)
FROM transaction
GROUP BY
month,
year;
根据操作的逻辑顺序更好的 SQL 语句
如果您希望您的 SQL 根据我提到的 SQL 操作的逻辑顺序保持可移植性和正确性,我建议您改为这样编写:
Field<?> month = DSL.month(DSL.date(TRANSACTION.CREATION_DATE));
Field<?> year = DSL.year(DSL.date(TRANSACTION.CREATION_DATE));
dsl.select(month.as("month"), year.as("year"), DSL.sum(TRANSACTION.VALUE))
.from(TRANSACTION)
.groupBy(month, year)
.fetch();
请注意,我已将别名移至 SELECT
子句,而在 GROUP BY
子句中,我现在引用了完整的列表达式。这将产生以下查询:
SELECT
month(date(transaction.creation_date)) as month,
year(date(transaction.creation_date)) as year
sum(transaction.value)
FROM transaction
GROUP BY
month(date(transaction.creation_date)),
year(date(transaction.creation_date));
完整的表达式现在扩展为GROUP BY
子句,您无需手动重复它们。
【讨论】:
非常感谢您的解释,@Lukas Eder 目前我被如何从 TRANSACTION.CREATION_DATE 创建日期的问题所阻止,因为数据库中的数据类型很长,它是unix 时间戳。 @AnnaIraHurnaus:我很乐意回答一个新的、单独的问题 这里是单独的问题:***.com/questions/60848890/…以上是关于如何在 Jooq 中按月和年将毫秒翻译成日期和分组?的主要内容,如果未能解决你的问题,请参考以下文章