我正在使用JOOQ在我的java代码中编写SQL。我将以下查询写入PostgreSQL数据库:'查询:获取已检查任务的总数以及完成任务所需的总时间。通过执行(endtime-starttime)从表“workevents”计算任务的总时间。但是在这里我获取在所有任务上花费的总时间。
with taskdata as (
select taskid from unittest.tasks
where projectname='test'and status='checked'
),
workevents as(
select (endtime-starttime) diff ,unittest.workevents.taskid as
workeventtaskid from unittest.workevents ,taskdata
where taskdata.taskid=unittest.workevents.taskid
)
select sum(workevents.diff),count(distinct workeventtaskid) from
workevents;
我已将它转换为下面的jooQ AS:
final String sql =
with(TASK_INFO_WRAPPER)
.as(select(TASK_ID).from(TASK_TABLE)
.where(PROJECT_NAME.eq(param()).and(TASK_STATUS.eq("checked"))))
.with(WORKEVENT_INFO_WRAPPER)
.as(select(TASK_END_TIME.sub(TASK_START_TIME).as("diff"),
WORKEVENT_TASK_ID.as("workeventtaskid"))
.from(WORKEVENT_TABLE, table(name(TASK_INFO_WRAPPER)))
.where("workeventinfo.taskid=taskinfo.taskid"))
.select().getSQL(ParamType.INDEXED);
但是我无法得到“diff”的总和(日期的差异)。在JOOQ中有任何函数可以将sql语句“select sum(workevents.diff)”转换为JOOQ。
我已经尝试了sum(field)函数,但它给出了编译时错误,因为sum用于数字。在这里我计算两个日期(差异)的差异的累积和。
当使用-
运算符实现日期差异时,所有RDBMS的行为都略有不同,这就是为什么通常建议使用jOOQ的DSL.dateDiff()
或DSL.timestampDiff()
。
WITH
WITH
通常用于将问题分解为SQL中较小的问题。但在某些时候,这种分解会导致更复杂的查询,而不是像你的情况那样。特别是在使用jOOQ时,通常建议避免使用常见的表表达式(WITH
)或派生表,这不仅是因为它们在jOOQ中更难表达,而且因为它们并没有真正为查询增加价值。
您的查询可以这样写:
select
sum(e.endtime - e.starttime),
count(distinct e.taskid)
from unittest.tasks t
join unittest.workevents e on t.taskid = e.taskid
where t.projectname = 'test' and t.status = 'checked'
这显然很容易转化为jOOQ。