MENU

mysql-groupby在sum函数统计

March 7, 2025 • 默认分类

表结构如下

CREATE TABLE `wa_fundcc` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
  `aid` int NOT NULL DEFAULT '0',
  `created_at` datetime DEFAULT NULL COMMENT '创建时间',
  `updated_at` datetime DEFAULT NULL COMMENT '更新时间',
  `merchant_no` varchar(255) DEFAULT NULL COMMENT '商户号',
  `chconfigid` int NOT NULL DEFAULT '0',
  `ordernum` int DEFAULT '0' COMMENT '订单总数',
  `amount` double(10,2) DEFAULT '0.00' COMMENT '总金额',
  `success` int DEFAULT '0' COMMENT '成功单数',
  `total` double(10,2) DEFAULT '0.00' COMMENT '成功金额',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=103 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='资金汇总';

业务需求

在groupby去重之前,需要对ordernum,amount,success,total这4个字段做求和操作

向deepseek提问

我给你一段mysql的sql语句,你帮我转换成laravel orm的语句。语句如下:SELECT
  *,
  sum( ordernum ) AS ordernum_sum,
  sum( amount ) AS amount_sum,
  sum( success) as success_sum,
  sum( total) as total_sum
FROM
  `wa_fundcc` 
GROUP BY
  chconfigid,
  created_at 
ORDER BY
  id DESC

以下是deepseek给出的方法。

将给定的 MySQL 查询转换为 Laravel Eloquent ORM 的代码如下:

WaFundcc::selectRaw('*, 
        SUM(ordernum) AS ordernum_sum, 
        SUM(amount) AS amount_sum, 
        SUM(success) AS success_sum, 
        SUM(total) AS total_sum')
    ->groupBy(['chconfigid', 'created_at'])
    ->orderByDesc('id')
    ->get();

注意事项:

  1. 严格模式问题: 若 MySQL 启用了 ONLY_FULL_GROUP_BY 模式,SELECT * 可能会导致错误。建议仅选择需要的字段或调整数据库配置。
  2. 字段歧义: 如果分组字段(如 created_at)在不同表中存在同名,需用表名前缀明确指定(如 wa_fundcc.created_at)。
  3. 模型配置: 确保 WaFundcc 模型已正确定义表名(默认类名蛇形复数,可手动设置 protected $table = 'wa_fundcc';)。

优化建议:
若不需要所有字段,可优化为仅选择分组字段和聚合结果:

WaFundcc::select(['chconfigid', 'created_at'])
    ->selectRaw('SUM(ordernum) AS ordernum_sum')
    ->selectRaw('SUM(amount) AS amount_sum')
    ->selectRaw('SUM(success) AS success_sum')
    ->selectRaw('SUM(total) AS total_sum')
    ->groupBy(['chconfigid', 'created_at'])
    ->orderByDesc('id')
    ->get();

再次提问

如果使用DB查询构造器呢,不适用模型的方式

回答

使用 Laravel 的 DB 查询构造器实现该 SQL 查询的代码如下:

DB::table('wa_fundcc')
    ->selectRaw('*, 
        SUM(ordernum) AS ordernum_sum, 
        SUM(amount) AS amount_sum, 
        SUM(success) AS success_sum, 
        SUM(total) AS total_sum')
    ->groupBy(['chconfigid', 'created_at'])
    ->orderByDesc('id')
    ->get();

关键说明:

  1. selectRaw
    直接通过原生表达式实现 SELECT *, SUM(...),保留原始 SQL 的聚合逻辑。
  2. 严格模式警告
    若 MySQL 启用 ONLY_FULL_GROUP_BYSELECT * 会导致错误。可改用以下方式优化:

    DB::table('wa_fundcc')
        ->select('chconfigid', 'created_at') // 明确指定分组字段
        ->selectRaw('SUM(ordernum) AS ordernum_sum')
        ->selectRaw('SUM(amount) AS amount_sum')
        ->selectRaw('SUM(success) AS success_sum')
        ->selectRaw('SUM(total) AS total_sum')
        ->groupBy(['chconfigid', 'created_at'])
        ->orderByDesc('id')
        ->get();
  3. 表名前缀(可选)
    若存在联表查询字段冲突,可通过 DB::raw 明确指定表名:

    ->groupBy(['chconfigid', DB::raw('wa_fundcc.created_at')])

两种方式的区别:

  • DB 构造器:直接操作表,适合简单查询或非模型关联场景。
  • Eloquent 模型:适合需要模型关联、属性转换等复杂操作。

根据业务场景选择即可。