【问题标题】:Diesel: Adding result of subqueriesDiesel:添加子查询的结果
【发布时间】:2021-08-18 21:48:03
【问题描述】:

给定以下表格:

accounts (
  id INTEGER,
  opening_balance INTEGER,
)

transactions (
  debit INTEGER,
  credit INTEGER,
  amount INTEGER

  foreign key debit references accounts (id),
  foreign key credit references accounts (id)
)

我要执行以下 SQL 查询:

select
  id,
  opening_balance
  + (select sum(amount) from transactions where debit = account_id)
  - (select sum(amount) from transactions where credit = account_id)
from accounts;

我尝试过这样的事情:

accounts
    .select((
        id,
        opening_balance
            + transactions::table
                .select(sum(transactions::amount))
                .filter(transactions::debit.eq(id))
            - transactions::table
                .select(sum(transactions::amount))
                .filter(transactions::credit.eq(id)),
    ))

虽然此查询的各个部分工作正常,但我无法编译它。

the trait bound 
`diesel::query_builder::SelectStatement<schema::transactions::table, diesel::query_builder::select_clause::SelectClause<aggregate_folding::sum::sum<diesel::sql_types::Integer, schema::transactions::columns::amount>>, diesel::query_builder::distinct_clause::NoDistinctClause, diesel::query_builder::where_clause::WhereClause<diesel::expression::operators::Eq<schema::transactions::columns::debit, schema::fiscal_year_accounts::columns::account_id>>>: diesel::Expression`
is not satisfied
required because of the requirements on the impl of `AsExpression<diesel::sql_types::Integer>` for 
`diesel::query_builder::SelectStatement<schema::transactions::table, diesel::query_builder::select_clause::SelectClause<aggregate_folding::sum::sum<diesel::sql_types::Integer, schema::transactions::columns::amount>>, diesel::query_builder::distinct_clause::NoDistinctClause, diesel::query_builder::where_clause::WhereClause<diesel::expression::operators::Eq<schema::transactions::columns::debit, schema::fiscal_year_accounts::columns::account_id>>>`

+- 运算符处理静态值,但我怎样才能让它们处理子查询?

【问题讨论】:

    标签: rust rust-diesel


    【解决方案1】:

    首先:始终提供一个完整的最小示例来说明您的问题。这包括所有使用的 crate 的确切版本、使您的代码实际产生此错误消息的所有相关导入、带有所有帮助和通知语句的完整错误消息以及在柴油情况下生成的模式文件。

    回答您的问题:您错过了两次对.single_value() 的调用,这是将查询转换为可用作表达式的子查询所必需的。两个子查询都返回一个Nullable&lt;BigInt&gt;,因此需要opening_balance 作为匹配类型。

    为了完整起见,请参阅下面的工作代码

    #[macro_use]
    extern crate diesel;
    use diesel::prelude::*;
    
    table! {
        accounts {
            id -> Integer,
            // changed to `BigInt` as a sum of `Integer` returns a `BigInt`
            opening_balance -> BigInt,
        }
    }
    
    table! {
        transactions {
            id -> Integer,
            amount -> Integer,
            debit -> Integer,
            credit -> Integer,
        }
    }
    
    allow_tables_to_appear_in_same_query!(accounts, transactions);
    
    fn test() {
        use self::accounts::dsl::*;
        use diesel::dsl::sum;
    
        let _q = accounts.select((
            id,
            opening_balance.nullable() // call `.nullable()` here to explicitly mark it as potential nullable
                + transactions::table
                    .select(sum(transactions::amount))
                    .filter(transactions::debit.eq(id))
                    .single_value() // call `.single_value()` here to transform this query into a subquery
                - transactions::table
                    .select(sum(transactions::amount))
                    .filter(transactions::credit.eq(id))
                    .single_value(), // call `.single_value()` here to transform this query into a subquery
        ));
    }
    

    【讨论】:

    • 嗨 weiznich,是的,虽然我认为我已经包含了所有相关信息,但 MCVE 丢失了......感谢您以任何方式解决问题!我不知道single_value(),这是缺少的部分。
    猜你喜欢
    • 2019-12-10
    • 1970-01-01
    • 2020-08-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-10
    • 2017-07-03
    • 2017-07-06
    • 1970-01-01
    相关资源
    最近更新 更多