C#Linq Datatable按日期时间分组

时间:2019-03-28 11:18:08

标签: c# linq datetime

我有一个看起来像这样的数据表

enter image description here

我试图实现的输出在图片中进行了描述,我想在其中按日期时间的月份和我想的代理进行分组。到目前为止,这就是我所拥有的。

            DataTable dtTemp = new DataTable();
            dtTemp.Columns.Add("Agent", typeof(string));
            dtTemp.Columns.Add("Amount", typeof(decimal));
            dtTemp.Columns.Add("Date", typeof(DateTime));

            dtTemp = dtTemp.AsEnumerable()
           .GroupBy(r => r[0])
           .Select(g =>
           {
               var row = dt.NewRow();

               row[0] = g.Key;
               row[1] = g.Sum(r => (decimal)r[1]);

               return row;
           })
           .CopyToDataTable();

任何想法如何实现这一目标?

谢谢!

3 个答案:

答案 0 :(得分:1)

通过分析帖子,您需要按列Agent分组数据表行,并且仅按列Date分组月份和年份。

您需要使用一个临时数据表dt,该数据表可以保存结果数据表result中每一列的数据类型。

因此CopyToDataTable()会将所有dtTemp组数据复制到具有临时result列数据类型的新dt数据表中。

DataTable dt = new DataTable();
dt.Columns.Add("Agent", typeof(string));
dt.Columns.Add("Amount", typeof(decimal));
dt.Columns.Add("Date", typeof(string));


DataTable result = dtTemp.AsEnumerable()
     .Select(x => new
     {
         Agent = x.Field<string>("Agent"),
         Amount = x.Field<decimal>("Amount"),
         Date = x.Field<DateTime>("Date").ToString("MM-yyyy")
     })
     .GroupBy(x => new { x.Agent, x.Date })
     .Select(g =>
     {
         var r = dt.NewRow();

         r["Agent"] = g.Key.Agent;
         r["Amount"] = g.Sum(c => c.Amount);
         r["Date"] = g.FirstOrDefault().Date;

         return r;
     })
     .CopyToDataTable();

输出:

enter image description here

答案 1 :(得分:0)

var temp = dtTemp.AsEnumerable().GroupBy(grp => new { grpmonth = Convert.ToDateTime(grp["Date"]).Month, grpyear = Convert.ToDateTime(grp["Date"]).Year, grpagent = grp["Agent"] })
                                 .Select(val =>
                                     {
                                         var row = dtTemp.NewRow();

                                         row["Agent"] = val.FirstOrDefault()["Agent"];
                                         row["Amount"] = val.Sum(amt => Convert.ToDecimal(amt["Amount"]));
                                         row["Date"] = val.FirstOrDefault()["Date"];
                                         return row;
                                     }
                                     )
                                 .CopyToDataTable();

对于reference

答案 2 :(得分:0)

因此,从您的输入序列中,您希望所有用户都使用Agents,并且每月要使用Amounts的总数。

让我们假设您的DataTable是一个Rows序列,并且可以轻松地将其转换为Rows序列:

class RowData
{
    public string Agent {get; set}
    public DateTime Date {get; set;}
    public int Amount {get; set;}
}

IEnumerable<RowData> tableData = ...

如果您的问题是为Agent分配具有相等值的RowData组,然后再次对这些组进行分组以使年和月具有相等值,则是解决方案

var AgentsWithAmountsPerMonth = tableData
    .GroupBy(row => row.Agent,        // make groups of rows with same Agent

    // ResultSelector: get the Agent (=key), with all rows that have this Agent
    (agent, rowsWithThisAgent) => new
    {
        Agent = agent,

        // to calculate the totals per year/month, extract the year / month / amount
        TotalsPerMonth = rowsWithThisAgent.Select(row => new
        {
            Year = row.Date.Year,
            Month = row.Date.Month,
            Amount = row.Amount,
        })

        // and group by same Year / Month:
        .GroupBy(row => new {row.Year, row.Month},

            // ResultSelector
            (yearMonth, rowsWithThisYearMonth) => new
            {
                Year = yearMonth.Year,
                Month = yearMonth.Month,
                Total = rowsWithThisYearMont.Select(row => row.Amount).Sum(),

                // Or put the year and month in one field:
                Month = new DateTime(yearMonth.Year, yearMonth.Month, 1),
            },
    });



    });