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

如何在.NET Core中为动态生成的DataTable插入按客户分组的小计行

实现方案

提供两种可直接落地的实现方式,可根据你的业务场景选择:


方案1:C# 操作DataTable实现(改造成本最低)

你原有代码的问题在于:仅计算了全表总计,没有按客户分组计算,且直接把总计行加到表末尾,没有插入到对应客户分组的下方。
修正后代码如下:

private void InsertSubTotals(ref DataTable dt)
{
    // 筛选出需要求和的日期列(排除客户、交易ID两个非数值列)
    var sumColumns = dt.Columns.Cast<DataColumn>()
        .Where(col => col.ColumnName != "Client" && col.ColumnName != "TradeId")
        .ToList();

    // 按客户分组,倒序处理避免插入行时打乱后续分组的索引位置
    var clientGroups = dt.AsEnumerable()
        .GroupBy(row => row["Client"].ToString())
        .OrderByDescending(g => g.Max(row => dt.Rows.IndexOf(row)))
        .ToList();

    foreach (var group in clientGroups)
    {
        DataRow subTotalRow = dt.NewRow();
        subTotalRow["Client"] = group.Key;
        subTotalRow["TradeId"] = $"{group.Key} 小计";

        // 逐列计算当前客户的分组求和值
        foreach (var col in sumColumns)
        {
            int total = group.Sum(row => row.IsNull(col) ? 0 : Convert.ToInt32(row[col]));
            subTotalRow[col] = total;
        }

        // 把小计行插入到当前客户所有交易行的下一个位置
        int lastRowIndex = dt.Rows.IndexOf(group.Last());
        dt.Rows.InsertAt(subTotalRow, lastRowIndex + 1);
    }
}

方案2:SQL层面直接生成带小计的透视结果

如果你不想修改C#逻辑,可以直接调整动态透视SQL,预先生成客户小计行再透视,查询结果直接可用于导出:

DECLARE @cols2 AS NVARCHAR(MAX),
    @query2  AS NVARCHAR(MAX)

-- 生成动态日期列(注意替换为你实际业务中的日期字段名)
select @cols2 = STUFF((SELECT ',' + QUOTENAME(BusDate) 
                    from #t2
                    group by BusDate
                    order by BusDate asc
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query2 = N'
SELECT Client, TradeId, ' + @cols2 + N' 
FROM (
    -- 原始交易行,排序标记为1保证排在前面
    select Client, TradeId, BusDate, Amount, 1 as SortOrder
    from #t2
    UNION ALL
    -- 客户小计行,排序标记为2保证排在同客户交易行后面
    select Client, Client + '' 小计'' as TradeId, BusDate, SUM(Amount) as Amount, 2 as SortOrder
    from #t2
    group by Client, BusDate
) x
pivot 
(
    max(Amount) 
    for BusDate in (' + @cols2 + N')
) p 
ORDER BY Client, SortOrder, TradeId
'
exec sp_executesql @query2;

注意:上述SQL中的字段名请和你实际临时表的字段对齐,你原有代码中透视用的字段名CPartyName/CobDate/NotionalFX和建表的Client/BusDate/Amount不一致,需替换为实际字段名。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 16:45:00