JPQL中如何使用COUNT(*)?分组统计含空值行的实现方法
JPQL实现“所有子女宠物均为Rover”的客户ID查询方案
针对你需要筛选出所有子女的宠物名称都是Rover的客户ID需求,JPQL中可以通过以下方式替代Oracle SQL里的COUNT(*)来统计分组内的总行数:
修改后的JPQL查询语句
SELECT c.customerId FROM Customer c INNER JOIN c.customersChild cc LEFT JOIN cc.childsPet cp ON cp.name = 'Rover' GROUP BY c.customerId HAVING COUNT(cp.name) = COUNT(cc)
关键逻辑说明
替代COUNT(*)的方案:
原Oracle SQL中COUNT(*)统计分组内所有行(包括左连接产生的空值行),在JPQL中,由于我们通过INNER JOIN关联了客户的子女cc,每个分组的总行数等价于该客户的子女总数。使用COUNT(cc)可以准确统计这个总数(cc不会为空,因为是内连接),效果和原SQL的COUNT(*)完全一致。条件判断逻辑:
COUNT(cp.name)统计的是该客户子女中宠物名为Rover的数量(左连接中,若子女的宠物不是Rover,则cp.name为null,不会被COUNT统计)。- 当
COUNT(cp.name)等于COUNT(cc)时,说明该客户的所有子女的宠物都是Rover,符合筛选条件。
移除FETCH的原因:
原查询中的FETCH用于即时加载关联实体,但分组查询的结果是聚合后的客户ID,不需要加载cc和cp的实体数据。保留FETCH会违反JPQL规范(分组查询的SELECT子句仅允许分组字段和聚合函数),因此需要移除。
内容的提问来源于stack exchange,提问作者ft982016
相关产品推荐
相关产品推荐

