假设我们有类别 - 商品 一对多关系。我想这样做
SELECT c.*,
(SELECT COUNT(*) FROM items i WHERE i.catId=c.id)
AS itemCount
FROM category c
让我们说我们有一个Hibernate POJO“类别”。
我的第一个问题是我真的无法弄清楚从那个查询我得到一个List< Category>对象吧?我怎样才能访问“itemCount”?因为没有 Category.getItemCount()
其次,我如何编写Criteria查询?
由于
答案 0 :(得分:6)
似乎这是我正在寻找的答案(进入POJO):
@Formula(value="(SELECT COUNT(*) FROM Items i WHERE i.id = id)")
@Basic(fetch=FetchType.EAGER)
public Integer getItemCount() {
return this.taskCount;
}
答案 1 :(得分:2)
根据您的具体情况和创建视图的能力而定。我只想从你的查询中创建一个视图:
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
答案 2 :(得分:1)
受到@ a_horse评论的启发,我为了类似的目的,用真实的生命表进行了快速测试。
items.catID
上。还有更多,但在这里没用。)三名候选人。结果是一样的。查询计划和性能各不相同。
总运行时间:20.351 ms
SELECT c.*
,(SELECT COUNT(*) FROM items i WHERE i.catid = c.id) AS item_ct
FROM category c
总运行时间:36.320毫秒
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
总运行时间: 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)使用,其中多个子查询可以获利。在其他查询中,顺序扫描更快:无论如何都必须读取所有表。