NestJS中使用TypeORM实现HH:MM格式时长字段求和
实现ore字段总时长求和的两种方案
方案1:内存中计算(适合数据量小的场景)
直接修改你的totaleore方法,用数组reduce累加所有ore字段的时长即可,两种常用返回格式的实现如下:
返回十进制小时数(如16.5代表16小时30分钟)
async totaleore(id: number) { const values = await this.repo.find({ where: { IdPreventivo: id }, select: ['ore'] // 只查询需要的字段,减少性能消耗 }); return values.reduce((sum, item) => { const [h, m] = item.ore.split(':').map(Number); return sum + h + m / 60; }, 0); }
返回HH:MM格式的总时长
async totaleore(id: number) { const values = await this.repo.find({ where: { IdPreventivo: id }, select: ['ore'] }); // 先计算总分钟数 const totalMinutes = values.reduce((sum, item) => { const [h, m] = item.ore.split(':').map(Number); return sum + h * 60 + m; }, 0); // 转换为HH:MM格式,不足两位自动补零 const hours = Math.floor(totalMinutes / 60).toString().padStart(2, '0'); const minutes = (totalMinutes % 60).toString().padStart(2, '0'); return `${hours}:${minutes}`; }
方案2:数据库层面聚合计算(适合数据量大的场景,性能更高)
不需要把全量记录拉到内存计算,直接通过SQL聚合函数在数据库侧完成计算,资源消耗更低,以MySQL为例的实现如下:
async totaleore(id: number) { const result = await this.repo .createQueryBuilder('attivitaprev') .select('SEC_TO_TIME(SUM(TIME_TO_SEC(attivitaprev.ore)))', 'totalOre') .where('attivitaprev.IdPreventivo = :id', { id }) .getRawOne(); // 返回值直接是HH:MM格式的总时长 return result.totalOre; }
如果你使用的是其他数据库,只需要把时间转换函数替换为对应数据库的语法即可,比如PostgreSQL可以用
SUM(attivitaprev.ore::interval)实现相同效果。
内容的提问来源于stack exchange,提问作者riki
相关产品推荐
相关产品推荐

