求助:在Knex中连接3张表且保留重复列不合并
解决Knex多表连接后同名字段覆盖的问题
当连接movies、reviews、critics三张表时,由于reviews和critics存在同名字段(critic_id、created_at、updated_at),Knex默认会返回最后出现的字段值,导致这些字段被合并覆盖。要实现预期的JSON结构,需要通过字段别名区分+结果结构重组来解决:
具体实现代码
// 构造查询,给同名字段设置别名区分 knex('movies') .innerJoin('reviews', 'movies.movie_id', '=', 'reviews.movie_id') .innerJoin('critics', 'reviews.critic_id', '=', 'critics.critic_id') .select( // 电影基础字段 'movies.movie_id', 'movies.title', 'movies.runtime', 'movies.release_date', 'movies.created_at as movie_created_at', 'movies.updated_at as movie_updated_at', // 评论字段,保留自身的critic_id、时间字段 'reviews.review_id', 'reviews.critic_id as review_critic_id', 'reviews.content', 'reviews.score', 'reviews.created_at as review_created_at', 'reviews.updated_at as review_updated_at', // 影评人字段,用别名区分同名字段 'critics.critic_id', 'critics.name', 'critics.organization_name', 'critics.created_at as critic_created_at', 'critics.updated_at as critic_updated_at' ) .then(queryResults => { // 重组结果为预期的JSON结构 return queryResults.map(row => ({ // 电影信息 movie_id: row.movie_id, title: row.title, runtime: row.runtime, release_date: row.release_date, created_at: row.movie_created_at, updated_at: row.movie_updated_at, // 评论信息,还原自身的critic_id和时间字段 review: { review_id: row.review_id, critic_id: row.review_critic_id, content: row.content, score: row.score, created_at: row.review_created_at, updated_at: row.review_updated_at }, // 影评人信息,保留自身的critic_id和时间字段 critic: { critic_id: row.critic_id, name: row.name, organization_name: row.organization_name, created_at: row.critic_created_at, updated_at: row.critic_updated_at } })); }) .catch(err => console.error(err));
关键原理说明
- 字段别名:通过给
reviews和critics的同名字段添加不同前缀的别名(如review_critic_id、critic_created_at),避免查询结果中字段名冲突导致的覆盖。 - 结构重组:查询完成后,通过
map方法将扁平化的查询结果,重新组织成包含嵌套review和critic对象的结构,还原各自的critic_id、created_at、updated_at字段。
如果你的表字段更多,可以按需扩展select中的字段列表,核心逻辑是通过别名区分同名字段,再手动构造目标JSON结构。
内容的提问来源于stack exchange,提问作者Eric Owens
相关产品推荐
相关产品推荐

