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

Rust Diesel 1.4.8编写group by查询报NonAggregate错误如何修复

问题描述

使用Rust Diesel 1.4.8版本编写分组查询时遇到编译错误,项目依赖配置如下:

diesel = { version = "1.4.8", features = ["postgres","64-column-tables","chrono","serde_json"] }

最初编写的分组查询代码如下:

fpub fn get_bill_book_account_sum(){
use crate::diesel::GroupByDsl;
use diesel::dsl::max;
use crate::model::diesel::dict::dict_schema::test as bill_record_table;
let source_query = bill_record_table::table
    .group_by(bill_record_table::id)
    .select((max(bill_record_table::tags),bill_record_table::id))
    .filter(bill_record_table::dsl::tags.eq(9));
}

编译时抛出如下错误:

error[E0277]: the trait bound `aggregate_ordering::max::max<BigInt, columns::tags>: NonAggregate` is not satisfied
   --> src/main.rs:19:17
    |
19  |         .select((max(bill_record_table::tags),bill_record_table::id))
    |          ------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonAggregate` is not implemented for `aggregate_ordering::max::max<BigInt, columns::tags>`
    |          |
    |          required by a bound introduced by this call
    |
    = note: required because of the requirements on the impl of `diesel::Expression` for `(aggregate_ordering::max::max<BigInt, columns::tags>, columns::id)`
note: required by a bound in `diesel::QueryDsl::select`
   --> /Users/xiaoqiangjiang/.cargo/registry/src/mirrors.tuna.tsinghua.edu.cn-df7c3c540f42cdbd/diesel-1.4.8/src/query_dsl/mod.rs:291:20
    |
291 |         Selection: Expression,
    |                    ^^^^^^^^^^ required by this bound in `diesel::QueryDsl::select`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `rust-learn` due to previous error    

用于构造最小复现示例的相关代码如下:

  • 表schema定义:
table! {
    test (id) {
        id -> Int8,
        tags -> Int8,
    }
}
  • 对应模型定义:
// Generated by diesel_ext

#![allow(unused)]
#![allow(clippy::all)]

use std::io::Write;
use diesel::deserialize::FromSql;
use diesel::pg::Pg;
use diesel::serialize::{Output, ToSql};
use diesel::sql_types::Jsonb;
use rocket::serde::Serialize;
use serde::Deserialize;
use crate::model::diesel::dict::dict_schema::*;

#[derive(Queryable,Debug,Serialize,Deserialize,Default)]
pub struct Test {
    pub id: i64,
    pub tags: i64,
}
  • 最小复现main入口代码:
#[macro_use]
extern crate diesel;

mod model;

use diesel::{ ExpressionMethods, QueryDsl};

fn main() {
    get_bill_book_account_sum();
}


pub fn get_bill_book_account_sum(){
    use crate::diesel::GroupByDsl;
    use diesel::dsl::max;
    use crate::model::diesel::dict::dict_schema::test as bill_record_table;
    let source_query = bill_record_table::table
        .group_by(bill_record_table::id)
        .select((max(bill_record_table::tags),bill_record_table::id))
        .filter(bill_record_table::dsl::tags.eq(9));
}
错误原因

两个问题导致编译失败:

  1. 函数定义存在笔误:开头多写了一个f,把pub错写成fpub,属于基础语法错误。
  2. Diesel 1.4.x版本对聚合查询的链式调用顺序有严格类型校验要求:select方法必须在group_by方法之前调用。如果先调用group_by再调用select,Diesel的类型系统会误将聚合函数(比如示例中的max)识别为普通非聚合列做校验,最终抛出NonAggregate trait未实现的错误。
修复方法

修正笔误,同时调整查询构造器的调用顺序,把select放到group_by之前即可,修改后的可正常编译的代码如下:

pub fn get_bill_book_account_sum(){
    use crate::diesel::GroupByDsl;
    use diesel::dsl::max;
    use crate::model::diesel::dict::dict_schema::test as bill_record_table;
    let source_query = bill_record_table::table
        .select((max(bill_record_table::tags),bill_record_table::id))
        .group_by(bill_record_table::id)
        .filter(bill_record_table::dsl::tags.eq(9));
}

补充说明:Diesel 1.x版本写聚合查询时,固定遵循select -> group_by -> having -> filter/order/limit的链式调用顺序,就不会触发这类类型校验错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 08:42:15