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

Java POJO映射含IF条件SELECT语句的非SELECT DISTINCT方案咨询

可行映射方案如下:

1. SQL层GROUP BY聚合方案

你当前左连接产生的重复行可以通过分组替代SELECT DISTINCT,直接按教师唯一标识(teacher_id)+ 其他非聚合查询字段分组,三个薪资字段用SUM/MAX聚合即可,SQL示例:

SELECT 
  t.teacher_id,
  -- 其他需要查询的教师基础字段
  SUM(IF(job = 'teacher' AND teachers_department.id = 1, teacher_salary, 0)) AS teacher_salary_by_department_one,
  SUM(IF(job = 'teacher' AND teachers_department.id = 2, teacher_salary, 0)) AS teacher_salary_by_department_two,
  SUM(IF(job = 'teacher' AND teachers_department.id = 3, teacher_salary, 0)) AS teacher_salary_by_department_three
FROM 主表 t
LEFT JOIN teacher_salary ts ON t.teacher_id = ts.teacher_id
LEFT JOIN teachers_department td ON ts.department_id = td.id
GROUP BY t.teacher_id -- 补充所有非聚合的查询字段

单教师单部门薪资的场景下,SUM和MAX效果一致,分组后每行对应唯一教师,ORM框架可直接按字段名自动映射到POJO属性。

2. ORM框架自定义结果映射方案

MyBatis场景

可通过<resultMap>显式绑定字段与POJO属性,也可以先关联查询出教师的所有薪资集合,再通过POJO的get方法动态计算三个部门薪资,无需在SQL中写IF逻辑:

<resultMap id="TeacherPojoMap" type="com.xxx.TeacherPojo">
  <id property="teacherId" column="teacher_id"/>
  <!-- 其他基础字段映射 -->
  <collection property="salaryList" ofType="com.xxx.TeacherSalary" 
              column="teacher_id" select="querySalaryByTeacherId"/>
</resultMap>

POJO中补充逻辑:

// 临时存储薪资集合,不需要可设置为transient
private List<TeacherSalary> salaryList;

public BigDecimal getTeacher_salary_by_department_one() {
  return salaryList.stream()
    .filter(s -> "teacher".equals(s.getJob()) && s.getDepartmentId() == 1)
    .map(TeacherSalary::getTeacherSalary)
    .findFirst()
    .orElse(BigDecimal.ZERO);
}
// 另外两个部门薪资同理实现对应get方法

JPA/Hibernate场景

直接在POJO字段上使用@Formula注解注入计算逻辑,查询时框架会自动拼接成查询字段完成映射:

@Formula("IF(job = 'teacher' AND teachers_department.id = 1, teacher_salary, 0)")
private BigDecimal teacher_salary_by_department_one;

@Formula("IF(job = 'teacher' AND teachers_department.id = 2, teacher_salary, 0)")
private BigDecimal teacher_salary_by_department_two;

@Formula("IF(job = 'teacher' AND teachers_department.id = 3, teacher_salary, 0)")
private BigDecimal teacher_salary_by_department_three;

确保实体类的表关联配置正确即可正常使用。

3. Java服务层手动聚合方案

先查询所有关联后的原始数据,在代码层按teacher_id分组后遍历计算三个字段的值,示例逻辑:

// 查询原始关联数据
List<Map<String, Object>> rawRecords = jdbcTemplate.queryForList(rawQuerySql);
// 按教师ID分组
Map<Long, List<Map<String, Object>>> teacherGroup = rawRecords.stream()
  .collect(Collectors.groupingBy(record -> (Long) record.get("teacher_id")));

List<TeacherPojo> result = new ArrayList<>();
for (Map.Entry<Long, List<Map<String, Object>>> entry : teacherGroup.entrySet()) {
  TeacherPojo pojo = new TeacherPojo();
  pojo.setTeacherId(entry.getKey());
  BigDecimal dep1Salary = BigDecimal.ZERO, dep2Salary = BigDecimal.ZERO, dep3Salary = BigDecimal.ZERO;
  
  for (Map<String, Object> record : entry.getValue()) {
    String job = (String) record.get("job");
    Integer depId = (Integer) record.get("department_id");
    BigDecimal salary = (BigDecimal) record.get("teacher_salary");
    if ("teacher".equals(job) && depId == 1) {
      dep1Salary = salary;
    } else if ("teacher".equals(job) && depId == 2) {
      dep2Salary = salary;
    } else if ("teacher".equals(job) && depId == 3) {
      dep3Salary = salary;
    }
  }
  
  pojo.setTeacher_salary_by_department_one(dep1Salary);
  pojo.setTeacher_salary_by_department_two(dep2Salary);
  pojo.setTeacher_salary_by_department_three(dep3Salary);
  result.add(pojo);
}

内容的提问来源于stack exchange,提问作者user15425589

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 15:24:01