Sequelize关联三张表查询异常:无法获取全部目标数据
问题分析与解决方案
从生成的原始SQL能看出两个核心问题:
- User表关联过滤错误:INNER JOIN User时额外加了
"user"."id" = '6'的条件,直接过滤掉了userID不为6的第三行记录。 - sharedUser查询条件失效:生成的SQL把sharedUser查询转为
IN ('{"id":"6"}'),但sharedUser是jsonb数组格式(如[{"id":"6"}]),IN操作无法匹配数组内容。
步骤1:修正User表关联逻辑
移除include中User模型的where条件,因为你需要关联的是Share记录对应的创建者用户,而非强制关联当前ID=6的用户。修改后的User关联部分:
{ model: User, required: true, attributes: [...columns from the table], // 保留你需要的字段列表 }
修改后JOIN条件仅保留"Share"."userID" = "user"."id",不会过滤userID不为6的Share记录。
步骤2:修正sharedUser的查询条件
由于sharedUser是jsonb数组,需要检查数组内是否存在id等于目标用户ID的元素。替换原有的查询逻辑为数组存在性校验:
const sharedData = await this.shareRepository.findAll({ attributes: ['userID', 'sharedUser', 'roomId', 'applicationId'], where: { [Op.or]: [ { userID: userId }, // 检查jsonb数组中是否包含id等于目标userId的元素 Sequelize.where( Sequelize.literal(`EXISTS (SELECT 1 FROM jsonb_array_elements("sharedUser") AS su WHERE su->>'id' = ?)`), userId ), ], }, include: [ { model: Application, required: true, attributes: [...columns from the table], // 保留你需要的字段列表 }, { model: User, required: true, attributes: [...columns from the table], // 保留你需要的字段列表 }, ], });
效果验证
修改后生成的SQL会:
- WHERE条件变为
"Share"."userID" = '6' OR EXISTS (SELECT 1 FROM jsonb_array_elements("sharedUser") AS su WHERE su->>'id' = '6'),能正确匹配前两行(userID=6)和第三行(sharedUser数组含id=6)。 - JOIN User表时仅通过
"Share"."userID" = "user"."id"关联,不会过滤第三行记录。
如果你的userId是数字类型,可以将查询中的su->>'id' = ?改为su->>'id'::integer = ?,确保类型完全匹配。
内容的提问来源于stack exchange,提问作者John Oliver
相关产品推荐
相关产品推荐

