NestJS TypeORM中loadRelationCountAndMap排序遇未知列问题
解决TypeORM中loadRelationCountAndMap后排序报"unknown column"错误
你遇到的问题根源是:loadRelationCountAndMap是TypeORM在查询结果返回后,将计数映射到实体属性的逻辑,数据库执行的SQL语句里并没有userSpotCount这类字段,直接用orderBy引用这些属性自然会提示未知列。
要实现按计数排序,必须让排序的字段成为SQL查询的一部分,以下是两种可行的解决方案:
方案一:子查询计算计数并作为select字段
通过addSelect添加子查询来计算关联表的计数,给计数设置别名后,就能直接用这个别名排序,同时保留loadRelationCountAndMap来映射实体属性:
await this.userRepository .createQueryBuilder('user') .leftJoinAndSelect('user.roles', 'roles') // 添加spot计数的子查询,别名userSpotCount .addSelect((qb) => { return qb.select('COUNT(spot.id)', 'userSpotCount') .from(SpotEntity, 'spot') // 替换成你的Spot实体类 .where('spot.userId = user.id'); }, 'userSpotCount') .loadRelationCountAndMap('user.postCount', 'user.post', 'post', qb => qb.where('post.type =:type', { type: 'post' }), ) .loadRelationCountAndMap('user.userSpotCount', 'user.spot', 'spot') .loadRelationCountAndMap( 'user.itineraryCount', 'user.post', 'post', qb => qb.where('post.type =:type', { type: 'itinerary' }), ) .where('roles.name = :name', { name: request.user_type }) .orderBy('userSpotCount', 'ASC'); // 现在可以直接引用别名排序
如果需要按postCount或itineraryCount排序,同理添加对应的子查询:
// 添加postCount的子查询 .addSelect((qb) => { return qb.select('COUNT(post.id)', 'postCount') .from(PostEntity, 'post') // 替换成你的Post实体类 .where('post.userId = user.id') .andWhere('post.type = :postType', { postType: 'post' }); }, 'postCount') // 添加itineraryCount的子查询 .addSelect((qb) => { return qb.select('COUNT(post.id)', 'itineraryCount') .from(PostEntity, 'post') .where('post.userId = user.id') .andWhere('post.type = :itineraryType', { itineraryType: 'itinerary' }); }, 'itineraryCount') // 然后就可以排序 .orderBy('postCount', 'DESC')
方案二:LeftJoin+GroupBy+Count
通过leftJoin关联表,用COUNT函数计算数量,配合groupBy实现计数,同样可以用别名排序:
await this.userRepository .createQueryBuilder('user') .leftJoinAndSelect('user.roles', 'roles') .leftJoin('user.spot', 'spot') .loadRelationCountAndMap('user.postCount', 'user.post', 'post', qb => qb.where('post.type =:type', { type: 'post' }), ) .loadRelationCountAndMap( 'user.itineraryCount', 'user.post', 'post', qb => qb.where('post.type =:type', { type: 'itinerary' }), ) .where('roles.name = :name', { name: request.user_type }) .addSelect('COUNT(DISTINCT spot.id)', 'userSpotCount') // 用DISTINCT避免重复计数 .groupBy('user.id') // 必须按user主键分组 .orderBy('userSpotCount', 'ASC');
两种方案都能让数据库识别到排序字段,解决"unknown column"的错误,同时保持返回结果中包含映射后的计数属性。
内容的提问来源于stack exchange,提问作者Atri Madhu
相关产品推荐
相关产品推荐

