【问题标题】:How can I count the number of result groups in QueryDSL?如何计算 QueryDSL 中的结果组数?
【发布时间】: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)&gt;=10‌​0) tbl;如果你得到答案请告诉我。

标签: java sql jpa jpql querydsl


【解决方案1】:

jpa 和 jql 我帮不了你,但这是一个有趣的 SQL 问题...

什么 RDMS?以下适用于 MS SQL Server。您可以使用连接、不同和计数来确定连接 x 和 y 时有多少唯一值。当您按 x,y 分组时,这应该是相同的行数。

select count(distinct CAST(x as char(10)) + CAST(y as char(10)))
from tasks;

【讨论】:

  • 实际上,我得到了一个 SQL 解决方案,在我的问题中使用了 subselect。我只是有问题如何将其告诉 JPA(和 QueryDSL)。 (顺便说一下,我正在使用 Postgresql。)
  • 所以您实际上是在连接这些行,然后在结果上使用“distinct”来查看总数?我会尝试是否可以在 QueryDSL 中实现,并且它是否实际上比仅检索所有内容并依靠客户端计算更快。
  • 正确。连接,然后只计算不同的值。我承认这不是一个理想的解决方案,但我只是接受了在 from 子句中找到没有子查询的聚合查询的行数的挑战,你说这在 QueryDSL 中是不可能的。希望它在某种程度上有所帮助。
猜你喜欢
  • 2012-08-30
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 2021-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-12
相关资源
最近更新 更多