如何使用QueryDSL筛选出分组内无CUSTOMER_ID空值的LOCATION
如何使用QueryDSL筛选出分组内无CUSTOMER_ID空值的LOCATION
嗨,我来帮你搞定这个问题!你的需求很明确:要从指定的LOCATION列表里,筛选出完全没有CUSTOMER_ID为null的记录的地点(也就是Amsterdam和Paris)。看你已经写了基础的QueryDSL代码,那我们直接在having子句里补充核心逻辑就行,也可以给你另一种更直观的子查询方案~
方案一:用having子句统计空值数量
这种方式最贴合你现有的代码结构,核心思路是对每个LOCATION分组,统计其中CUSTOMER_ID为null的记录数,只要这个数量是0,就符合你的要求:
List<String> locations = Lists.newArrayList("London", "Amsterdam", "Berlin", "Paris"); List<String> result = new JPAQuery<>(entityManager) .select(orders.location) .from(orders) .where(orders.location.in(locations)) .groupBy(orders.location) // 关键逻辑:统计分组内CUSTOMER_ID为null的记录数等于0 .having(orders.customerId.isNull().count().eq(0L)) .fetch();
这里的orders.customerId.isNull()会生成一个布尔表达式,count()方法会统计该表达式为true的记录数量。当这个数量为0时,就说明该LOCATION下没有任何一条记录的CUSTOMER_ID是null,正好匹配你的需求。
方案二:用子查询排除存在空值的LOCATION
如果你觉得子查询的逻辑更清晰,也可以用这种方式:先找出所有存在CUSTOMER_ID为null的LOCATION,然后在主查询里排除这些地点:
List<String> locations = Lists.newArrayList("London", "Amsterdam", "Berlin", "Paris"); QOrders subOrders = new QOrders("subOrders"); // 注意这里要给子查询的实体起别名,避免和主查询冲突 // 构建子查询:检查当前LOCATION是否存在CUSTOMER_ID为null的记录 JPASubQuery<Boolean> subQuery = new JPASubQuery<>() .select(Expressions.asBoolean(true)) .from(subOrders) .where(subOrders.location.eq(orders.location) .and(subOrders.customerId.isNull())); List<String> result = new JPAQuery<>(entityManager) .select(orders.location) .from(orders) .where(orders.location.in(locations) .and(subQuery.notExists())) // 排除存在空值的LOCATION .groupBy(orders.location) .fetch();
这种方式的逻辑更直白:先定位所有“有问题”的LOCATION(包含空CUSTOMER_ID的),然后从目标列表里把它们去掉,剩下的就是你想要的结果。
两种方案都能实现你的需求,你可以根据自己的代码习惯选择~ 记得确保QOrders是你通过QueryDSL生成的实体类,类名和你的实际项目保持一致哦。
备注:内容来源于stack exchange,提问作者stacktrace2234
相关产品推荐
相关产品推荐

