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

Laravel9下YajraBox Datatables服务端添加合计行方法问询

解决方案:Laravel 9 + Yajra Datatables 服务端模式添加全局合计

针对百万级数据量的场景,完全可以通过 Query Builder 在数据库层面处理合计逻辑,避免集合操作或前端API的局限性。以下提供两种实用方案:

方案一:每页页脚显示全局合计(推荐)

该方案将全局合计数据附加到Datatables响应中,前端在页脚渲染,确保每页都能看到全量数据的统计结果,性能最优。

1. 后端代码调整

先封装重复的筛选条件闭包,再分别获取业务数据和合计数据:

use DB;
use DataTables;

// 封装筛选条件,避免重复代码
$filterCallback = function ($query) use ($finalItem) {
    foreach ($finalItem as $keyword) {
        if (is_numeric($keyword)) {
            $query->orWhere('login', '=', $keyword);
        } else {
            $query->orWhere('group', 'like', '%' . $keyword . '%');
        }
    }
};

// 原业务数据查询
$result = DB::table('table')
    ->select('column1', 'column2', 'column3', 'column4', 'column5', 'column6', 'column7', 'column8', 'column9', 'column10', 'Group', 'Login', 'time_msc')
    ->whereBetween('time_msc', [$fromDate, $toDate])
    ->where($filterCallback)
    ->latest('deal');

// 获取全局合计数据
$totals = DB::table('table')
    ->select(
        DB::raw('SUM(column1) as total_column1'),
        DB::raw('SUM(column2) as total_column2'),
        DB::raw('SUM(column3) as total_column3')
    )
    ->whereBetween('time_msc', [$fromDate, $toDate])
    ->where($filterCallback)
    ->first();

// 将合计数据附加到Datatables响应中
return Datatables::of($result)
    ->with('totals', [
        'column1' => $totals->total_column1 ?? 0,
        'column2' => $totals->total_column2 ?? 0,
        'column3' => $totals->total_column3 ?? 0,
    ])
    ->toJson();

2. 前端渲染逻辑

通过Datatables的drawCallback回调,从响应中取出合计数据并渲染到页脚:

$('#your-table-id').DataTable({
    serverSide: true,
    ajax: {
        url: '/your-data-api-url',
        dataSrc: function (json) {
            // 缓存合计数据
            window.tableTotals = json.totals;
            return json.data;
        }
    },
    drawCallback: function () {
        const api = this.api();
        const footer = api.table().footer();
        
        // 将合计值渲染到对应列的页脚(索引对应column1/2/3的列位置)
        $(footer).find('td:eq(0)').text(`合计: ${window.tableTotals.column1}`);
        $(footer).find('td:eq(1)').text(window.tableTotals.column2);
        $(footer).find('td:eq(2)').text(window.tableTotals.column3);
    }
});

方案二:合计行作为数据最后一行(仅最后一页显示)

如果需要将合计行作为数据的一部分展示在最后一页,可通过UNION ALL合并业务查询与合计查询:

use DB;
use DataTables;

$filterCallback = function ($query) use ($finalItem) {
    foreach ($finalItem as $keyword) {
        if (is_numeric($keyword)) {
            $query->orWhere('login', '=', $keyword);
        } else {
            $query->orWhere('group', 'like', '%' . $keyword . '%');
        }
    }
};

// 原业务数据查询,添加标识字段区分普通行与合计行
$dataQuery = DB::table('table')
    ->select(
        'column1', 'column2', 'column3', 'column4', 'column5',
        'column6', 'column7', 'column8', 'column9', 'column10',
        'Group', 'Login', 'time_msc',
        DB::raw('0 as is_total')
    )
    ->whereBetween('time_msc', [$fromDate, $toDate])
    ->where($filterCallback)
    ->latest('deal');

// 合计行查询,字段数量与类型需与原查询完全匹配
$totalQuery = DB::table('table')
    ->select(
        DB::raw('SUM(column1) as column1'),
        DB::raw('SUM(column2) as column2'),
        DB::raw('SUM(column3) as column3'),
        DB::raw('NULL as column4'),
        DB::raw('NULL as column5'),
        DB::raw('NULL as column6'),
        DB::raw('NULL as column7'),
        DB::raw('NULL as column8'),
        DB::raw('NULL as column9'),
        DB::raw('NULL as column10'),
        DB::raw('\'合计\' as `Group`'),
        DB::raw('NULL as Login'),
        DB::raw('NULL as time_msc'),
        DB::raw('1 as is_total')
    )
    ->whereBetween('time_msc', [$fromDate, $toDate])
    ->where($filterCallback);

// 合并两个查询,确保合计行在最后
$finalQuery = $dataQuery->unionAll($totalQuery)->orderBy('is_total', 'asc')->orderBy('deal', 'desc');

return Datatables::of($finalQuery)->toJson();

注意事项

  • 两种方案均在数据库层面完成统计,不会将全量数据加载到内存,适合百万级数据场景。
  • 使用UNION ALL时,需保证两个查询的字段数量、顺序、数据类型完全一致,否则会抛出SQL错误。
  • 合计查询与业务查询共享相同的筛选条件,确保统计结果与业务数据范围一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 06:35:27