【发布时间】:2014-10-30 16:14:48
【问题描述】:
如何在 QueryDSL(Java 中)中实现组计数?
背景
我正在对表格实施分页搜索,我想在返回结果之前对其进行分组。
除了通常的LIMIT x OFFSET y查询,我还想接收总行数。
这是一页的(简化的)SQL 查询:
SELECT x, y, MAX(z)
FROM tasks
WHERE y > 10
GROUP BY x, y
LIMIT 10 OFFSET 0
为了检索行数,我尝试使用幼稚的COUNT(*) 而不是x, y, MAX(z),如下所示:
SELECT COUNT(x)
FROM tasks
WHERE y > 10
GROUP BY x, y
不幸的是,这不会产生一个包含前一个查询返回的组数的行,而是每个组一个行,每个组都有被分组在一起的行数——就像聚合函数一样,COUNT当出现GROUP BY 时改变其含义。 (至少在 Postgresql 中,我们在这里使用的是什么。)
我们可以通过使用第一个 SELECT 语句作为 from 子句中的子选择来检索总计数:
SELECT COUNT(*)
FROM ( SELECT x, y, MAX(z)
FROM tasks
WHERE y > 10
GROUP BY x, y
)
现在是困难的部分:我们如何在 JPQL 和/或 QueryDSL 中做到这一点?
前两个查询是由如下代码生成的:
QTask qTask = QTask.task;
Expression<?>[] groupExps = { qTask.x, qTask.y };
Predicate predicate = qTask.y.gt(10);
List<Result> results = getQueryDSL().createQuery()
.from(qTask)
.where(predicate)
.groupBy(groupExps)
.offset(0)
.limit(10)
.list(ConstructorExpression.create(Result.class,
qTask.x
qTask.y,
qTask.z.max()))
Long total = getQuerydsl().createQuery()
.from(qTask)
.where(predicate)
.groupBy(groupExps)
.singleResult(qTask.x.count());
看起来像JPA/JPQL doesn't support subselects other than in WHERE or HAVING-clauses,即它们在 FROM 子句中是不可能的。这似乎是 QueryDSL for JPA 也不支持它们的原因。
有没有办法重写这个语句,或者以某种方式解决这个限制?
【问题讨论】:
-
我也在寻找类似问题的解决方案,如下面的
select count(*) as count from (select count(stock0_.stock_id) as col_0_0_ from stock stock0_ having sum(stock0_.QTY)>=100) tbl;如果你得到答案请告诉我。
标签: java sql jpa jpql querydsl