原生SQL语句如何正确转换为Bookshelf/Knex查询语句
问题解答
核心问题原因
SQL的逻辑运算符优先级为AND > OR,同时你之前的Knex写法没有对需要成组的条件加括号分组,直接平级调用orWhere/andWhere,导致生成的SQL逻辑和预期完全不符。
你提供的原生SQL实际执行逻辑等价于:
select * from o where o.id = 1 or ( o.id = 2 and (o.is_a = true or o.is_b = true) and o.status = 'good' );
如果你的实际需求是id为1或2、同时满足状态正常、同时is_a或is_b为真(绝大多数业务场景的真实需求,你写原始SQL时可能漏加了id条件的括号),那么正确的原生SQL应该是:
select * from o where (o.id = 1 or o.id = 2) and (o.is_a = true or o.is_b = true) and o.status = 'good';
两种场景的正确Knex写法
场景1:严格对齐你给出的原生SQL逻辑
await O.forge() .query(qb => { qb.where('id', 1) .orWhere(group => { group.where('id', 2) .where('status', 'good') .where(subGroup => { subGroup.where('is_a', true).orWhere('is_b', true) }) }) })
场景2:实际业务常用逻辑(id在指定范围+状态正常+is_a/is_b满足其一)
await O.forge() .query(qb => { qb.whereIn('id', [1, 2]) .where('status', 'good') .where(subGroup => { subGroup.where('is_a', true).orWhere('is_b', true) }) })
之前写法的错误点
你两次尝试的代码都会生成如下逻辑的SQL:
select * from o where is_a = true or (is_b = true and id in (1,2) and status = 'good')
和预期逻辑完全不同,所以返回结果不一致。
内容的提问来源于stack exchange,提问作者Ash
相关产品推荐
相关产品推荐

