You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.16 11:19:35