如何在Hibernate中进行SELECT查询包括子查询COUNT(*)

假设我们有一个类别 – 项目 一对多关系。 我想这样做

SELECT c.*, (SELECT COUNT(*) FROM items i WHERE i.catId=c.id) AS itemCount FROM category c 

让我们说我们有一个Hibernate POJO“类别”。

我的第一个问题是我真的无法弄清楚从那个查询我得到一个List 对象吗? 我怎样才能访问“itemCount”? 因为没有Category.getItemCount()

其次,我如何编写Criteria查询?

谢谢

似乎这是我正在寻找的答案(进入POJO):

 @Formula(value="(SELECT COUNT(*) FROM Items i WHERE i.id = id)") @Basic(fetch=FetchType.EAGER) public Integer getItemCount() { return this.taskCount; } 

根据您的具体情况和创建视图的能力。 我只想从您的查询中创建一个视图:

 CREATE VIEW CategoryItemsView AS SELECT c.*, (SELECT COUNT(*) FROM items i WHERE i.catId=c.id) AS itemCount FROM category c 

之后你可以查询你喜欢的…

 SELECT * FROM CategoryItemsView WHERE ItemCount = 5 

此外,您可以使用GROUP BY来实现类似的结果,但这取决于您的列和表的架构。

所以,像这样:

 SELECT c.COLUMN1, c.COLUMN2, COUNT(*) AS ItemCount FROM category c inner join items i on i.catID = c.Id GROUP BY c.COLUMN1, c.COLUMN2 HAVING COUNT(*) = 2 

关于查询

受到@ a_horse评论的启发,我为了类似的目的,用真实的生命表进行了快速测试。

  • 80个类别
  • 6862项
  • 最佳索引(在items.catID 。还有更多,但在这里items.catID 。)

三名候选人。 结果是相同的。 查询计划和性能各不相同。

1)每个类别的子选择(Seregwethrin的原始版本)

总运行时间:20.351 ms

 SELECT c.* ,(SELECT COUNT(*) FROM items i WHERE i.catid = c.id) AS item_ct FROM category c 

2)LEFT JOIN,然后是GROUP

总运行时间:36.320 ms

 SELECT c.* ,count(*) AS item_ct FROM category c LEFT JOIN items i ON i.catid = c.id GROUP BY c.catid; -- prim. key of category 

3)GROUP,然后LEFT JOIN

总运行时间: 18.588 ms

 SELECT c.* ,item_ct FROM category c LEFT JOIN ( SELECT catid ,count(*) AS item_ct FROM items GROUP BY catid ) i ON i.catid = c.id 

所以,我的第一个建议没有任何好处。 正如预期的那样(经过一番思考),版本3)表现最佳。 这也是有道理的:如果先计算,然后再加入,则需要更少的连接操作。

对于较大的表,性能的差异将变得更加明显,尤其是对于更多类别。

为了2)工作,你需要PostgreSQL 9.1和category.id需要是主键。
对于旧版本,您必须列出GROUP BY子句中的所有非聚合列。

我一般切换到LEFT JOIN ,因为原始查询包括没有关联项的类别。

items.catID上的索引仅用于1)多个子查询可以获利的情况。 在其他查询中,顺序扫描更快:无论如何都必须读取所有两个表。