C # Linq Datatable groupby дата / месяц - PullRequest
1 голос
/ 28 марта 2019

У меня есть таблица данных, которая выглядит следующим образом

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 ]

1 голос
/ 28 марта 2019

Анализируя ваше сообщение, вам нужно сгруппировать по строкам таблицы данных по столбцу 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

0 голосов
/ 28 марта 2019

Итак, из вашей входной последовательности вы хотите, чтобы все использовали Agents, с общей суммой Amounts в месяц.

Давайте предположим, что ваш DataTable представляет собой последовательность строк, и что его легко можно преобразовать в последовательность строк:

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

IEnumerable<RowData> tableData = ...

Решение, если ваша проблема состоит в том, чтобы создать группы 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),
            },
    });



    }); 
0 голосов
/ 28 марта 2019
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();

Для ссылка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...