You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Rust的Diesel中编写多个显式inner_join?

使用Diesel实现显式多表Inner Join

问题背景

我用Rust的actix_web和Diesel开发API,需要实现这条SQL查询:

SELECT * FROM customers c
JOIN users u ON u.name = c.customer_no
JOIN address a ON c.fk_address = a.id
WHERE a.name='10715';

同时有两个疑问:

  1. Diesel中显式连接与隐式连接的区别是什么?
  2. 隐式多表连接可以正常运行,但显式多连接的写法总是报错,正确的写法应该是怎样的?

显式与隐式连接的区别

  • 隐式连接:依赖Diesel通过宏(如belongs_to)预定义的表间关系,写法简洁,无需手动指定连接条件
users.inner_join(posts)
  • 显式连接:不依赖预定义关系,直接在查询中明确指定连接条件,灵活性更高
users.inner_join(posts::table.on(posts::id.eq(user::id)))

我的尝试

隐式多连接写法可以正常工作:

users.inner_join(posts.inner_join(comments))

但以下显式多连接写法无法运行:

users.inner_join(
    posts::table.on(posts::id.eq(user::id))
        .inner_join(comments::table.on(comments::id.eq(post::id)))
)

解决方案

正确的显式多连接写法

Diesel中显式多连接需要让主表依次调用inner_join,每次传入带显式连接条件的目标表,不能嵌套链式调用inner_join在on子句之后。

对应目标SQL的正确代码如下:

use schema::{customers, users, address};

// 假设&conn是已建立的数据库连接
let query_results = customers::table
    // 显式指定customers与users的连接条件
    .inner_join(users::table.on(users::name.eq(customers::customer_no)))
    // 显式指定customers与address的连接条件
    .inner_join(address::table.on(customers::fk_address.eq(address::id)))
    // 添加WHERE条件
    .filter(address::name.eq("10715"))
    // 加载为三个表的Model元组(需确保Model已正确生成)
    .load::<(customers::Model, users::Model, address::Model)>(&conn)?;

错误原因说明

之前的写法错误在于:posts::table.on(...)返回的是JoinOnClause类型,该类型不支持直接调用inner_join。必须让主表(或上一步的连接结果)直接调用inner_join,传入带on条件的目标表,Diesel才能正确解析多表连接逻辑。

内容的提问来源于stack exchange,提问作者ilepix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 18:16:04