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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 15:24:03