在单个查询中使用 JPA 进行多个聚合

Posted

技术标签:

【中文标题】在单个查询中使用 JPA 进行多个聚合【英文标题】:Multiple aggregations using JPA in a single query 【发布时间】:2018-10-13 12:06:42 【问题描述】:

我有一个表来存储项目,需要根据多个过滤器选择聚合数据。

CREATE TABLE Parents(id int, name varchar)
CREATE TABLE Items(id int, parent_id int, field_A int,field_B int)

现在我想计算 field_A=1 的项目,并且我还想计算所有父母的 field_A=1 和 field_B=2 的项目。

SELECT p.id, p.name, count1, count2 FROM Parents p
INNER JOIN 
(SELECT count(id) as count1, parent_id FROM Items WHERE field_A=1 GROUP BY 
parent_id) select1 ON select1.parent_id=p.id
INNER JOIN 
(SELECT count(id) as count2, parent_id FROM Items WHERE field_A=1 AND 
field_B=2 GROUP BY parent_id)
select2 ON select2.parent_id=p.id

使用 JPA 作为 JEE 应用程序的一部分来实现这一点的正确方法是什么? 据我了解,JPA 不支持子查询,我必须使用本机查询。 部分测试数据:

insert into items(id,parent_id, field_A, field_B) values(1,1,1,1);
insert into items(id,parent_id, field_A, field_B) values(2,1,1,2);
insert into items(id,parent_id, field_A, field_B) values(3,1,2,1);
insert into items(id,parent_id, field_A, field_B) values(4,1,2,2);
insert into items(id,parent_id, field_A, field_B) values(5,2,1,2);
insert into items(id,parent_id, field_A, field_B) values(6,2,1,3);
insert into items(id,parent_id, field_A, field_B) values(7,1,1,3);
insert into items(id,parent_id, field_A, field_B) values(8,2,1,2);
insert into items(id,parent_id, field_A, field_B) values(9,2,1,2);

【问题讨论】:

【参考方案1】:

呃,加入子查询。让我先简化你的 SQL:

SELECT 
    p.id, 
    p.name,
    SUM(1) AS count1, 
    SUM(CASE i.field_B WHEN 2 THEN 1 ELSE 0 END) AS count2
FROM Items i
JOIN Parents p ON i.parent_id = p.id
WHERE i.field_A = 1
GROUP BY p.id, p.name

你的 JPQL 然后变成:

SELECT
    p.id,
    p.name,
    SUM(1),
    SUM(CASE WHEN i.fieldB = 2 THEN 1 ELSE 0 END)
FROM Items i
JOIN i.parent p
WHERE i.fieldA = 1
GROUP BY p.id, p.name

据我了解,JPA 不支持子查询

它们是,只是不在FROM 子句中(不过,一些 JPA 提供程序也支持这一点)。

【讨论】:

以上是关于在单个查询中使用 JPA 进行多个聚合的主要内容,如果未能解决你的问题,请参考以下文章

在单个聚合查询 mongodb 中组合多个 $samples

详细教程一文参透MongoDB聚合查询

单个查询中的多个聚合和分组

单个 Prisma 查询中的 LEFT JOINS 和聚合

SQL 中的多个聚合从单个值的查询开始

如何使用蒙德里安聚合单个维度的多个层次结构?