Sequelize中如何使用动态生成字段的值作为查询过滤条件
失效原因
totalCount: Sequelize.col('modelTwoCount')写法不生效有两个核心原因:
- SQL执行顺序中WHERE子句运行在SELECT聚合计算、GROUP BY操作之前,此时
modelTwoCount聚合别名还未生成,无法被引用 modelTwoCount是动态计算的聚合字段,不属于ModelOne、ModelTwo的实际表结构,Sequelize解析WHERE条件时不会将其识别为合法列
实现方法
聚合结果的过滤必须使用HAVING子句,该子句在GROUP BY和聚合运算完成后才执行,完全匹配当前过滤场景,修改后代码如下:
ModelOne.findAll({ subQuery: false, include: { model: ModelTwo, where: { completed: false, }, required: true // 生成内连接,排除无符合条件关联ModelTwo的ModelOne数据,可按需调整 }, group: ['ModelOne.id', 'ModelTwo.modelOneId'], // 补充ModelOne主键到分组字段,避免ONLY_FULL_GROUP_BY模式报错 attributes: { include: [[sequelize.fn("COUNT", sequelize.col("ModelTwo.modelOneId")), "modelTwoCount"]], }, // 过滤逻辑移到having中,判断ModelOne.totalCount等于聚合统计值 having: { totalCount: Sequelize.col('modelTwoCount') }, // 若所用数据库不支持HAVING引用SELECT别名,可改用下方兼容性更强的写法,直接在HAVING中做聚合对比 // having: sequelize.where( // sequelize.col('ModelOne.totalCount'), // '=', // sequelize.fn("COUNT", sequelize.col("ModelTwo.modelOneId")) // ) });
补充说明
- 若关联关系默认生成左连接,不加
required: true会查出无符合条件ModelTwo关联的ModelOne数据,聚合值为0,可根据业务需求决定是否添加该配置 - 若执行时提示
modelTwoCount列不存在,直接替换为注释里的第二种having写法即可,该写法兼容所有主流数据库
内容的提问来源于stack exchange,提问作者Ростислав Попов
相关产品推荐
相关产品推荐

