rust 柴油机从where子句中的count相关记录中删除

ctehm74n  于 2023-01-09  发布在  其他
关注(0)|答案(1)|浏览(134)
    • bounty将在5天后过期**。回答此问题可获得+50声望奖励。tedtanner希望引起更多人对此问题的关注:请提供一个好的解决方案示例。如果使用了很少使用的Diesel函数,请提供相应文档的链接,并简要说明该函数的功能。

我正在使用Rust Diesel库,并有一个如下所示的模式:
该模式如下所示:

table! {
    table1 (id) {
        id -> Uuid,
        ...
    }
}

table! {
    table2 (id) {
        id -> Uuid,
        ...
    }
}

table! {
    table3 (id) {
        id -> Uuid,
        table1_id -> Uuid,
        table2_id -> Uuid,
        ...
    }
}

...

allow_tables_to_appear_in_same_query!(table1, table2, table3, ...);

我很难用Rust Diesel表示这个SQL查询:

DELETE FROM table1 t1
WHERE (
  SELECT COUNT(*) FROM table3 t3 WHERE t3.table2_id = {id_value}
  AND t1.id = t3.table1_id
) = 1;

table3中与table2中的特定记录关联的相关记录的计数为1时,查询的预期结果是删除table1中的记录。实际表1、2和3分别称为budgetsusersuser_budgets。如果这对我所做的事情有帮助的话,我希望能够删除一个用户的所有未"共享"的预算,这意味着它们也通过user_budgets表与其他用户相关联。
我不知道如何在柴油机中实现这一点。我尝试过这样做:

diesel::delete(
   table1.filter(
        dsl::count(
            table3_fields::table2_id
                .eq({id_value})
                .and(table1_fields::id.eq(table3_fields::table1_id)),
        )
        .eq(1),
    ),
)

这行不通我得到了以下错误(使用搜索/替换进行了编辑,以匹配我的假设模式):

error[E0277]: the trait bound `diesel::expression::is_aggregate::Yes: MixedAggregates<diesel::expression::is_aggregate::No>` is not satisfied
   --> path/to/file.rs:345:21
    |
345 |             table1.filter(
    |                     ^^^^^^ the trait `MixedAggregates<diesel::expression::is_aggregate::No>` is not implemented for `diesel::expression::is_aggregate::Yes`
    |
    = help: the following other types implement trait `MixedAggregates<Other>`:
              <diesel::expression::is_aggregate::Yes as MixedAggregates<diesel::expression::is_aggregate::Never>>
              <diesel::expression::is_aggregate::Yes as MixedAggregates<diesel::expression::is_aggregate::Yes>>
    = note: required for `diesel::expression::grouped::Grouped<diesel::expression::operators::Eq<diesel::expression::count::count::count<diesel::sql_types::Bool, diesel::expression::grouped::Grouped<diesel::expression::operators::And<diesel::expression::grouped::Grouped<diesel::expression::operators::Eq<table3::columns::table2_id, diesel::expression::bound::Bound<diesel::sql_types::Uuid, uuid::Uuid>>>, diesel::expression::grouped::Grouped<diesel::expression::operators::Eq<table1::columns::id, table3::columns::table1_id>>>>>, diesel::expression::bound::Bound<BigInt, i64>>>` to implement `NonAggregate`
    = note: required for `SelectStatement<FromClause<table1::table>>` to implement `FilterDsl<diesel::expression::grouped::Grouped<diesel::expression::operators::Eq<diesel::expression::count::count::count<diesel::sql_types::Bool, diesel::expression::grouped::Grouped<diesel::expression::operators::And<diesel::expression::grouped::Grouped<diesel::expression::operators::Eq<table3::columns::table2_id, diesel::expression::bound::Bound<diesel::sql_types::Uuid, uuid::Uuid>>>, diesel::expression::grouped::Grouped<diesel::expression::operators::Eq<table1::columns::id, table3::columns::table1_id>>>>>, diesel::expression::bound::Bound<BigInt, i64>>>>`

有没有办法做到这一点,而不诉诸sql_query
(FYI,我使用的是Postgres后端)

b1zrtrql

b1zrtrql1#

这应实现:

diesel::delete(table1::table).filter(
    table3::table
        .filter(table3::table2_id.eq(id_value))
        .filter(table1::id.eq(table3::table1_id))
        .count()
        .single_value()
        .eq(1),
);

debug_query()的输出看起来几乎相同:

DELETE  FROM "table1" WHERE ((SELECT COUNT(*) FROM "table3" WHERE (("table3"."table2_id" = $1) AND ("table1"."id" = "table3"."table1_id")) LIMIT $2) = $3) -- binds: [78e50fcc-6b13-4ee2-aece-4959f3a67f76, 1, 1]

我被绊倒了一段时间,因为我忘记了需要.single_value()才能将SELECT视为表达式。之后就相当简单了。完整的代码可用here on the playground
另见:

相关问题