如何在 Jooq 中按月和年翻译毫秒到日期和分组?
How to translate millis to date and group by month and year in Jooq?
我有以下 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
拥有的毫秒创建日期对象。
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?
写 SQL GROUP BY
时的一个常见混淆是 the logical order of SQL operations。虽然在句法上,SELECT
似乎出现在 GROUP BY
之前,但逻辑上顺序是相反的。这意味着您不能真正从 GROUP BY
子句中引用 SELECT
子句中的列。
有些方言可能已经实现了例外 "for convenience",但这通常非常令人困惑。我建议不要那样做。
但是要解决你的问题:
生产你想生产的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
子句中,您无需手动重复它们。
我有以下 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
拥有的毫秒创建日期对象。
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?
写 SQL GROUP BY
时的一个常见混淆是 the logical order of SQL operations。虽然在句法上,SELECT
似乎出现在 GROUP BY
之前,但逻辑上顺序是相反的。这意味着您不能真正从 GROUP BY
子句中引用 SELECT
子句中的列。
有些方言可能已经实现了例外 "for convenience",但这通常非常令人困惑。我建议不要那样做。
但是要解决你的问题:
生产你想生产的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
子句中,您无需手动重复它们。