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

TypeORM一对多关系下如何用QueryBuilder按日期排序获取共享设备最新Data数据

实现方案

首先先修正你实体中的一处关联配置错误:当前Devices实体的@OneToMany关联参数填写错误,第二个参数需要指向Data实体中关联Devices的devices属性,否则关联查询会异常,修正后代码如下:

// Devices实体中修正后的OneToMany配置
@OneToMany(() => Data, data => data.devices)
Data: Data[];

以下是两种符合需求的QueryBuilder实现方式:

方案1:返回映射好的实体对象(更易用)

通过leftJoinAndMapOne直接将每个设备的最新Data映射到Devices实体的额外属性中,返回结果为标准实体数组:

  1. 先给Devices实体新增可选的最新数据属性:
// 在Devices类中添加
latestData?: Data;
  1. 查询代码:
import { getRepository } from 'typeorm';

const devicesWithLatestData = await getRepository(Devices)
  .createQueryBuilder('device')
  // 过滤所有共享状态为true的设备
  .where('device.shared = :isShared', { isShared: true })
  // 关联映射每个设备的最新Data记录
  .leftJoinAndMapOne(
    'device.latestData',
    Data,
    'data',
    'data.id_data = (SELECT MAX(subData.id_data) FROM data subData WHERE subData.id_device = device.id_device)'
  )
  .getMany();

这里用自增主键id_data的最大值判断最新记录,如果你需要严格按创建时间匹配,可以将子查询中的MAX(subData.id_data)替换为subData.time = (SELECT MAX(subData2.time) FROM data subData2 WHERE subData2.id_device = device.id_device)即可。

方案2:返回原始查询结果

如果只需要原始字段数据,可以用子查询关联的方式实现:

import { getConnection } from 'typeorm';

const result = await getConnection()
  .createQueryBuilder()
  .select('device.id_device', 'deviceId')
  .addSelect('device.name', 'deviceName')
  .addSelect('data.*')
  .from(Devices, 'device')
  .where('device.shared = :isShared', { isShared: true })
  // 子查询获取每个设备的最新Data ID
  .leftJoin(
    qb => qb.select('MAX(subData.id_data)', 'maxDataId')
      .addSelect('subData.id_device')
      .from(Data, 'subData')
      .groupBy('subData.id_device'),
    'latestData',
    'latestData.id_device = device.id_device'
  )
  // 关联拿到最新Data的完整字段
  .leftJoin(Data, 'data', 'data.id_data = latestData.maxDataId')
  .getRawMany();

内容的提问来源于stack exchange,提问作者Bartłomiej Pachel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 23:45:03