根据另一列的值对数据表中的列求和

时间:2012-09-23 12:42:05

标签: c# sql

我有一个数据库表,我将其用作报告的来源。表格布局看起来 喜欢。表1是较大数据库表的子集。但是对于报告我只需要某些列所以我使用下面给出的函数创建一个新的数据表

Value  Description   Hours
    1          A           2
    2          B           3
    3          C           5
    1          A           3
    2          B           4
    2          B           3
    3          C           3


private DataTable CreateFocusOfEffortData()
    {
        var dtChartData = new DataTable();
        dtChartData.Columns.Add("Description", typeof(string));
        dtChartData.Columns.Add("Hours", typeof(Double));
        var myDataView = ReportData.DefaultView;
        myDataView.RowFilter = "ActivityUnitID = " + _ActivityUnitID;
        for (var i = 0; i < myDataView.ToTable().Rows.Count; i++)
        {
            var dataRow = new Object[dtChartData.Columns.Count];
            dataRow[0] = ReportData.Rows[i]["Description"];
            dataRow[1] = csaConvert.ToDouble(ReportData.Rows[i]["Hours"]);
            dataRow[2] = ReportData.Rows[i]["Value"];
            dtChartData.Rows.Add(dataRow);
        }
        return dtChartData;
    }

现在我需要设计另一份包含上表摘要数据的报告。这个表应该 根据列[&#34;值]组合所有列的数据。例如,在我的例子中,我们在Value 1,2,3中有三个不同的值。结果表应该为所有三个值总计小时数。

    Value   Description  Hours
    1         A           5
    2         B           10
    3         C           8

现在我可以通过创建另一个存储过程来在sql中执行此操作,但我宁愿使用现有的数据表并编写C#函数来获取结果。有没有更简单的方法来实现这一点使用LINQ?

2 个答案:

答案 0 :(得分:6)

你采取了错误的做法。在SQL中这样做。

 SELECT value, description, sum(hours) as hours from tblData group by value, description;

以上内容将为您提供您在问题中显示的第二个表格。

这样做的原因是将数据传递给客户端应用程序只是为了让它直接传递给SQL会不必要地消耗内存和系统调用。此外,错误,错误,类型转换问题等的空间也少得多。

如果你真的想制作更窄的表(这通常是一个坏主意),那就这样做:

 SELECT value, description, hours from tblData into tblSkinnyData;

一般情况下,如果由于某种原因需要这个瘦表,你可以在主表上使用VIEW。

答案 1 :(得分:2)

您可以使用AsEnumerable()来使用LINQ,然后使用GroupBy ValueDescriptionSum Hours来设置第一行:

var result = dtChartData.AsEnumerable()
            .GroupBy(row => new
                {
                    Value = row.Field<int>("Value"),
                    Description = row.Field<string>("Description")
                })
            .Select(g =>
                {
                    var row = g.First();
                    row.SetField("Hours", g.Sum(r => r.Field<double>("Hours")));

                    return row;
                });

结果将返回IEnumerable<DataRow>,但如果您想返回DataTable,请使用:

var resultTable = result.CopyToDataTable();