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

如何使用TypeORM实现关联另一张表的id NOT IN条件查询

TypeORM 实现 NOT IN 子查询方案

你之前编写的代码只实现了tableA.id不等于单个固定id的判断,和你需要的「id不在tableB的a_id集合中」的逻辑完全不符,以下是符合需求的3种实现方式:

1. 嵌套子查询实现(和原生SQL逻辑完全对齐)

这种方式生成的SQL和你给出的原生SQL完全一致,不需要提前查询全量a_id,性能更优:

const result = await this.createQueryBuilder('tableA')
  .where(qb => {
    // 生成子查询:查询tableB中所有的a_id
    const subQuery = qb.subQuery()
      .select('tableB.a_id')
      .from('tableB', 'tableB')
      .getQuery();
    return `tableA.id NOT IN ${subQuery}`;
  })
  .getMany();

2. 关联查询实现(适配有实体关联的场景)

如果你已经在TableA和TableB实体中配置了一对多关联,用左连接加空判断的方式实现,大数据量下性能优于NOT IN写法:

// 实体定义示例
// TableA.entity.ts
@Entity()
export class TableA {
  @PrimaryGeneratedColumn()
  id: number;
  @OneToMany(() => TableB, tableB => tableB.a)
  tableBs: TableB[];
}

// TableB.entity.ts
@Entity()
export class TableB {
  @PrimaryGeneratedColumn()
  id: number;
  @ManyToOne(() => TableA, tableA => tableA.tableBs)
  @JoinColumn({ name: 'a_id' })
  a: TableA;
}

// 查询逻辑
const result = await this.createQueryBuilder('tableA')
  .leftJoin('tableA.tableBs', 'tableB')
  .where('tableB.id IS NULL')
  .getMany();

3. 数组参数实现(适合提前获取a_id集合的场景)

如果业务逻辑里已经提前拿到了所有a_id的集合,可以直接用TypeORM的数组参数语法传递:

// 先查询所有a_id
const aIdList = await this.dataSource.getRepository(TableB)
  .createQueryBuilder('tableB')
  .select('tableB.a_id', 'a_id')
  .getRawMany()
  .then(res => res.map(item => item.a_id));

// 执行NOT IN查询,注意数组参数要加...前缀
const result = await this.createQueryBuilder('tableA')
  .where('tableA.id NOT IN (:...aIdList)', { aIdList })
  .getMany();

内容的提问来源于stack exchange,提问作者saravanan mp

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 05:42:02