如何使用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
相关产品推荐
相关产品推荐

