我正在 Spring 数据存储库中使用 JPA 查询,该查询使用 DISTINCT 和 ORDER BY 子句 获取数据。该查询在没有 DISTINCT 的情况下工作,但添加它会导致以下错误:
Expression #1 of ORDER BY clause is not in SELECT list, references column 'entityName.auditTimestamp' which is not in SELECT list; this is incompatible with DISTINCT
@Query("SELECT DISTINCT new com.example.dto.MyDTO(entity.id, user.id, user.email, role.displayValue, practice.id, practice.name, entity.inactiveDate, entity.type, entity.status, entity.documentId) "
+ "FROM Entity entity "
+ "LEFT JOIN User user ON entity.userId = user.id "
......
+ "ORDER BY entity.auditTimestamp DESC")
处理这种情况的最佳方法是什么?
出现此错误的原因是,在使用 DISTINCT 时,SQL 要求 ORDER BY 子句中的列也位于 SELECT 列表中。当应用 DISTINCT 时,数据库会对投影中选择的字段进行排序,但实体.auditTimestamp 不包含在 SELECT 列表中,从而导致错误。
以下是解决此问题的一些方法:
@Query("SELECT DISTINCT new com.example.dto.MyDTO(entity.id, user.id, user.email, role.displayValue, practice.id, practice.name, entity.inactiveDate, entity.type, entity.status, entity.documentId, entity.auditTimestamp) "
+ "FROM Entity entity "
+ "LEFT JOIN User user ON entity.userId = user.id "
+ "ORDER BY entity.auditTimestamp DESC")
另一种方法是使用子查询。首先,根据所需字段获取不同的 ID,然后在主查询中按auditTimestamp 对结果进行排序。这是一个例子:
@Query("SELECT new com.example.dto.MyDTO(e.id, u.id, u.email, r.displayValue, p.id, p.name, e.inactiveDate, e.type, e.status, e.documentId) "
+ "FROM Entity e "
+ "LEFT JOIN User u ON e.userId = u.id "
+ "WHERE e.id IN (SELECT DISTINCT entity.id FROM Entity entity) "
+ "ORDER BY e.auditTimestamp DESC")
这可能需要根据您的实体结构调整查询,但它可以允许您在订购时保留 DISTINCT 逻辑。
@Query("SELECT new com.example.dto.MyDTO(entity.id, user.id, user.email, role.displayValue, practice.id, practice.name, entity.inactiveDate, entity.type, entity.status, entity.documentId) "
+ "FROM Entity entity "
+ "LEFT JOIN User user ON entity.userId = user.id "
+ "ORDER BY entity.auditTimestamp DESC")
List<MyDTO> results = repository.findAll();
List<MyDTO> distinctResults = results.stream().distinct().collect(Collectors.toList());