从数据表中求和不同的值

时间:2016-12-19 08:54:23

标签: c# datatable

我有这个数据表:

SECTION    CODE  DATE        VALUE
section1    20  jul 2013    31507976.71
section1    20  nov 2013    31643256.16
section1    20  dec 2013    28788554.96
section1    20  jan 2014    32297021.88
section1    20  feb 2014    29111554.83
section1    20  mar 2014    32789670.01
section1    20  apr 2014    32045399.52
section1    20  may 2014    33420106.37
section1    20  jun 2014    31246337.7
section1    20  jul 2014    31406327.47
section2    50  apr 2013    31219430.46
section2    50  may 2013    32200204.19
section2    50  jun 2013    32348605.39
section2    50  dec 2013    33158170.04
section2    50  jan 2014    33472813.18
section2    50  feb 2014    30875748.12
section2    50  mar 2014    34655429.31
section2    50  apr 2014    31894634.74
section2    50  may 2014    29467627.18
section2    50  jun 2014    31224988.16
section2    50  jul 2014    59455468.22
section3    20  apr 2013    29467627.18
section3    20  nov 2013    28230480.06
section3    20  dec 2013    27273436.72
section3    20  jan 2014    27074471.34
section3    20  may 2014    31396504.33
section3    20  jun 2014    29528727.08
section3    20  jul 2014    29630946.19

我想通过每个时期的特定代码获得总数。 恩。对于代码20,它将计算在第二列中具有代码20的每个部分并且按每个周期求和。 我应该得到一个这样的列表:

 Period      Code: 20
apr 2013    29467627.18
apr 2014    32045399.52
dec 2013    56061991.68
feb 2014    29111554.83
jan 2014    59371493.22
jul 2013    31507976.71
jul 2014    61037273.66
jun 2013    0
jun 2014    60775064.78
mar 2014    32789670.01
may 2013    0
may 2014    64816610.7
nov 2013    59873736.22

这是我尝试过的,但我只得到零值:

string code="20";
       List<string[]> data = new List<string[]>();
            List<string> period = new List<string>();           
            List<decimal> value = new List<decimal>();  
            decimal nr=0;
            foreach (DataRow dr in dt.Rows)
                if (dr[1].ToString().Equals(code))
                    period.Add(dr[2].ToString());
            }
        List<string>period2= period.Distinct().ToList();
            foreach (string p in period2) value.Add(0);
            for (int i = 0; i < period2.Count; i++)
            {
                foreach (DataRow dr in dt.Rows)
                { if (period2[i].Equals(dr[2].ToString()))
                        nr += Convert.ToDecimal(dr[3].ToString());
                }
                value[i] = nr;
            }
            for (int i = 0; i < period2.Count; i++)
            {
                data.Add(new string[] {period2[i], value[i].ToString()});
            }

3 个答案:

答案 0 :(得分:0)

我认为这可能会让您选择代码为20且日期大于2013年4月的所有行。

List<DataRow> result = urDataTable.Select("CODE == 20 AND DATE > #1/4/2013#");
foreach (DataRow row in result)
{
    //do
}

如果CODE是非数字护理,则20就像'20'一样

答案 1 :(得分:0)

您可以按日期和代码对结果进行分组。 然后你可以按代码过滤它们,以获得你想要的值。

我建议首先将结果映射到模型,这样比通过索引引用字符串数组更容易阅读。

这样的事情:

public class SectionModel
{
    public string SectionId { get; set; }
    public int Code { get; set; }
    public DateTime Date { get; set; }
    public decimal Value { get; set; }
}

var list = dt.Rows.Select(d => new SectionModel
            {
                SectionId = d[0],
                Code = Convert.ToInt32(d[1]),
                Date = Convert.ToDateTime(d[2]),
                Value = Convert.ToDecimal(d[3])
            });

            var results = list.GroupBy(row => new {row.Date, row.Code}, (key, rows) => new
            {
                period = key.Date,
                code = key.Code,
                value = rows.Sum(r => r.Value)
            })
                .Where(r => r.code == codeParameter)
                .ToList();

答案 2 :(得分:0)

您可以通过这样使用GroupBy来获取所需信息:

var aggregatedItems = items.GroupBy(x => new { x.Code, x.Period })
            .Select(g => new
            {
                Code = g.Key.Code,
                Period = g.Key.Period,
                Value = g.Sum(y => y.Value)
            });

之后您可以像这样访问它们(订购是可选的):

foreach (var item in aggregatedItems.OrderBy(x=>x.Code).ThenBy(x=>x.Period))
{
    Console.WriteLine($@"Code:{item.Code}\t\tPeriod:{item.Period}\tSum:{item.Value}");
}

Try it online