如何在Sequelize外键联表中实现带OR条件的关联查询
Sequelize 自定义关联OR条件实现方案
针对需要在内连接的ON条件中加入OR判断的场景,Sequelize 提供了完整的自定义关联规则配置能力,无需退回原生SQL即可实现等价查询逻辑。
关键配置调整
- 修正原有配置的拼写错误:代码中写的
require: true是无效配置,Sequelize 控制内连接的对应配置项为required: true,未配置时默认会生成左连接,和原生SQL的内连接逻辑不匹配。 - 关联
TownhouseFreeFreights子表时,通过on参数手动声明完整的ON逻辑,不再依赖模型默认的外键匹配规则,用Op.or操作符拼接两个关联判断条件。 - 将原SQL中
tf."minValue" >= 0的过滤规则,配置在对应子表的where参数中,和原查询逻辑保持一致。 - 原SQL中主表的
c.id = 1过滤规则,配置在findAll方法的顶层where参数中。
完整可运行代码示例
// 引入Sequelize核心操作符 const { Op } = require('sequelize'); getFreightRules(){ // 假设已完成Sequelize实例初始化,实例对象为sequelize return Customer.findAll({ // 对应原SQL where c.id = 1 where: { id: 1 }, include: [{ model: Townhouse, required: true, // 对应core."Customers" 和 core."Townhouses" 的内连接 include: [{ model: TownhouseFreeFreights, required: true, // 对应和portal."TownhouseFreeFreights"的内连接 // 自定义ON关联条件,完全匹配原SQL的ON逻辑 on: { [Op.or]: [ // 条件1:tf.townhouseid = t.id sequelize.where( sequelize.col('TownhouseFreeFreights.townhouseid'), '=', sequelize.col('Townhouse.id') ), // 条件2:tf.townhouseid is null sequelize.where( sequelize.col('TownhouseFreeFreights.townhouseid'), null ) ] }, // 对应原SQL中tf."minValue" >= 0的过滤条件 where: { minValue: { [Op.gte]: 0 } } }] }] }) }
实现注意事项
- 所有需要引用数据库字段的判断逻辑,必须用
sequelize.col()方法包裹,直接写字段名字符串会被Sequelize识别为普通文本值,导致关联逻辑完全失效。 - 如果你的模型在定义关联时已经配置了默认的外键匹配规则,Sequelize 会自动把默认规则和你自定义的
on条件用AND拼接,这种场景下需要手动在on中完整声明所有关联判断逻辑,避免出现逻辑冲突。 - 原SQL中
OR tf.townhouseid is null的内连接逻辑,会把所有townhouseid为null的TownhouseFreeFreights记录全量关联到查询结果集上,若出现返回数据重复,可通过给对应include项增加duplicating: false配置调整返回结构。
内容的提问来源于stack exchange,提问作者Daniel Guimaraes
相关产品推荐
相关产品推荐

