如何解决JPA 标准:按子字段排序给出错误
我有 3 个实体。 客户、流程和文档。
我想按文档的 updateDate
对客户进行排序。
我的实体如下所示;
客户-
@Entity
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OnetoMany(mappedBy = "customer",cascade = CascadeType.ALL,fetch = FetchType.LAZY)
private List<Process> processes = new ArrayList<>();
// getter,setter etc.
}
过程-
@Entity
public class Process {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String type;
@ManyToOne(fetch = FetchType.LAZY)
private Customer customer;
@OnetoMany(mappedBy = "process",fetch = FetchType.LAZY)
private List<Document> documents = new ArrayList<>();
//getter,setter etc.
}
文档-
@Entity
public class Document {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String note;
private LocalDateTime updateDate;
@ManyToOne(fetch = FetchType.LAZY)
private Process process;
}
我已经尝试了以下规范-
public static Specification<Customer> orderByDocumentUploadDate() {
return (root,query,criteriaBuilder) -> {
ListJoin<Customer,Process> processJoin = root.join(Customer_.processes);
ListJoin<Process,Document> documentJoin = processJoin.join(Process_.documents);
query.orderBy(criteriaBuilder.desc(documentJoin.get(Document_.updateDate)));
query.distinct(true);
return null;
};
}
它给出了以下错误-
错误:对于 SELECT disTINCT,ORDER BY 表达式必须出现在选择中 列表
select distinct customer0_.id as id1_0_,customer0_.name as name2_0_
from customer customer0_
inner join
process processes1_ on customer0_.id = processes1_.customer_id
inner join
document documents2_ on processes1_.id = documents2_.process_id
order by documents2_.update_date desc
limit ?
我也尝试过分组,如下所示-
public static Specification<Customer> orderByDocumentUploadDate() {
return (root,criteriaBuilder) -> {
ListJoin<Customer,Process> processJoin = root.join(Customer_.processes);
ListJoin<Process,Document> documentJoin = processJoin.join(Process_.documents);
query.orderBy(criteriaBuilder.desc(documentJoin.get(Document_.updateDate)));
query.groupBy(root.get(Customer_.id));
return null;
};
}
错误:“documents2_.update_date”列必须出现在 GROUP BY 中 子句或在聚合函数中使用
select
customer0_.id as id1_0_,customer0_.name as name2_0_
from
customer customer0_
inner join
process processes1_
on customer0_.id=processes1_.customer_id
inner join
document documents2_
on processes1_.id=documents2_.process_id
group by
customer0_.id
order by
documents2_.update_date desc limit ?
我可以通过下面的sql来实现; max()
在下面的 sql-
select customer.* from customer
inner join process p on customer.id = p.customer_id
inner join document d on p.id = d.process_id
group by customer.id
order by max(d.update_date);
但我不能这样做,使用 criteria
API。
你有什么建议吗?
解决方法
这是一个概念上的误解。
-
首先,您必须了解内连接的工作原理。在这种情况下,这部分是可以的:[join
process
table withdocument
table based ondocument.process_id = process.id
] -
其次,您需要根据文档的更新日期对客户进行排序
很遗憾,您在这里使用了 group by
。 GROUP BY
只返回 grouped by
所在的列。在这种情况下,它只会返回 customer_id
。
您可以对分组数据使用诸如 count()
、sum()
等聚合函数。
当您尝试访问 update_date
时,它会抛出以下错误:
ERROR: column "documents2_.update_date" must appear in the GROUP BY clause or be used in an aggregate function
现在,我们怎样才能摆脱这种情况?
- 因此,首先我们需要执行
join
来获取客户 ID。获得客户id后,我们应该按客户id对数据进行分组,然后使用max()获取每组的max_date(如果需要,则为最小值)
SELECT
customer_id,max(date) AS max_date
FROM
document
JOIN process ON process.id = document.process_id
GROUP BY customer_id
它将返回一个临时表,如下所示:
customer_id | 最大日期 |
---|---|
1 | 2020-10-24 |
2 | 2021-03-15 |
3 | 2020-09-24 |
4 | 2020-03-15 |
使用临时表,您现在可以按日期对 customer_id
进行排序
SELECT
customer_id,max_date
FROM
(SELECT
customer_id,max(date) AS max_date
FROM
document
JOIN process ON process.id = document.process_id
GROUP BY customer_id) AS pd
ORDER BY max_date DESC
希望这会有所帮助。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。