Knex v0.21.2三表连接查询失败求助
解决Knex三表连接中指定车辆ID的问题
看起来你在把原生SQL转成Knex查询的时候,卡在了车辆ID的过滤条件上。我帮你分析下问题所在,然后给出修正后的代码。
问题根源
你的原生SQL是在INNER JOIN tipo_servico_veiculo的时候,同时把v.id = :id作为连接条件的一部分。但在你写的Knex代码里,直接用andOn('v.id', '=', id)可能没有正确绑定参数——Knex可能把id当成了字符串字面量,而不是你传入的变量值,导致查询结果不符合预期。
另外,从SQL最佳实践来说,这种单表的过滤条件其实更适合放到WHERE子句里,让逻辑更清晰。
修正方案一(推荐:使用WHERE子句过滤)
把车辆ID的过滤条件单独抽出来放到where里,代码更易读,也避免了连接条件里的参数绑定问题:
const result = await knex('veiculo as v') // 先完成表之间的关联 .join('tipo_servico_veiculo as tsv', 'tsv.veiculo_id', '=', 'v.id') .join('tipo_servico as t', 't.id', '=', 'tsv.servico_id') .join('combustivel as c', 'v.id_combustivel', '=', 'c.id') // 添加车辆ID过滤条件 .where('v.id', id) // 补全你需要的所有字段(和原生SQL保持一致) .select( 'v.id as id_veiculo', 'v.placa', 'v.marca', 'v.exibicao', 'v.modelo', 'v.renavam', 'v.chassi', 'v.ano_fabri', 'v.ano_modelo', 'v.id_combustivel', 'v.capacidade_litros', 'v.cor', 'v.uf_placa', 'v.status', 't.id as id_servico', 't.servico', 'c.nome as combustivel' );
修正方案二(保持原生SQL的连接条件风格)
如果你一定要把v.id = id放在连接条件里,需要确保Knex正确绑定参数。你可以直接使用变量,Knex 0.21+版本会自动处理参数绑定,或者用knex.raw明确指定:
const result = await knex('veiculo as v') .join('tipo_servico_veiculo as tsv', function () { this.on('tsv.veiculo_id', '=', 'v.id') // 直接传入变量,Knex会自动绑定参数 .on('v.id', '=', id); // 或者用raw更明确:.on('v.id', knex.raw('?', [id])) }) .join('tipo_servico as t', 't.id', '=', 'tsv.servico_id') .join('combustivel as c', 'v.id_combustivel', '=', 'c.id') .select( 'v.id as id_veiculo', 'v.placa', 'v.marca', 'v.exibicao', 'v.modelo', 'v.renavam', 'v.chassi', 'v.ano_fabri', 'v.ano_modelo', 'v.id_combustivel', 'v.capacidade_litros', 'v.cor', 'v.uf_placa', 'v.status', 't.id as id_servico', 't.servico', 'c.nome as combustivel' );
额外提示
你原来的Knex代码里的select字段比原生SQL少了一些(比如renavam、chassi等),上面的代码已经帮你补全了,确保返回的字段和原生SQL一致。
内容的提问来源于stack exchange,提问作者Israel Silva
相关产品推荐
相关产品推荐

