最近开发项目需求,需要按客户分类展示最新一条拜访记录,所以就想到使用 max() 聚合函数和 group by 组合。具体的 sql 如下
SELECT ANY_VALUE(report.id) as id ,ANY_VALUE(report.name) as name , MAX(report.create_at) as created FROM report GROUP BY report.customer_id
查出来的数据 id ,name 和 created 不是对应的值。原因是:group by 对数据按哪个字段或哪几个字段进行排序,如果不在 group by 后的分组中使用聚合函数,一般只会返回各个分组中的第一条数, 查了资料发现可以使用 inner join 解决。
SELECT report.id AS id, report.name AS name, report.create_at AS create_at FROM report a JOIN (
SELECT ANY_VALUE(report.id) as id MAX(report.create_at) as created FROM report GROUP BY report.customer_id
) AS b
ON a.id=b.id AND a.create_at=b.created;
具体的 typeorm 的子查询语法如下:
await this.reportRepo.createQueryBuilder('report')
// group by max 组合问题,需要 inner jion 获取准确数据
.innerJoin(subQuery => {
return subQuery.select([
'cr.customer_id',
'MAX(cr.create_at) created',
'ANY_VALUE(cr.id) AS id',
])
.from(CallReport, 'cr')
.groupBy('cr.customer_id')
}, 'reportA', 'reportA.created = report.create_at AND reportA.customer_id = report.customer_id'))
.select([
'report.create_at created',
'report.id AS id',
])
.getRawMany();