从数据表中选择,按条件按多个列分组

Selecting from Datatable , Grouped by multiple Column with condition

我有一个数据表,其中有 4 个字段。

 ptime, Substation, ColumnTitle, ValueAmount

我想要具有最大 ValueAmount 的行,按 Substation 和 ColumnTitle 分组。所以假设这是我的数据表

 ptime,  Substation, ColumnTitle, ValueAmount
 --------------------------------------------
 '01:00'    'AA'       'A'          100
 '03:00'    'AA'       'A'          150
 '01:00'    'BB'       'A'          10
 '02:00'    'BB'       'A'          11
 '01:00'    'AA'       'C'          77
 '02:00'    'AA'       'C'          88
 '04:00'    'AA'       'C'          99

所以我想要

   ptime,  Substation, ColumnTitle, ValueAmount
 --------------------------------------------
 '03:00'    'AA'       'A'          150
 '02:00'    'BB'       'A'          11
 '04:00'    'AA'       'C'          99

用于此目的的最佳 linq 命令是什么? 我已经编程了:

 var newSort = from row in dtFinal.AsEnumerable()
   group row by new  {Substation = row.Field<string>("Substation"), 
            ColumnTitle= row.Field<string>("ColumnTitle")} into grp       
   select new
   {
     Substation = grp.Key.Substation,
     ColumnTitle = grp.Key.ColumnTitle,         
     ValueAmount = grp.Max(r => decimal.Parse(r.Field<string>("ValueAmount")))
   }; 

但在这种语法中我没有 ptime。我该怎么做。

谢谢

您可以按此值降序排列组以获得 "MaxRow",在那里您会找到 ptime:

var newSort = dtFinal.AsEnumerable()
    .GroupBy(row => new
    {
        Substation = row.Field<string>("Substation"),
        ColumnTitle = row.Field<string>("ColumnTitle")
    })
    .Select(g => new
    {
        g.Key.Substation,
        g.Key.ColumnTitle,
        MaxRow = g.OrderByDescending(row => decimal.Parse(row.Field<string>("ValueAmount"))).First()
    })
    .Select(x => new 
    {
        ptime = x.MaxRow.Field<string>("ptime"), // voilà
        x.Substation,
        x.ColumnTitle,
        ValueAmount = decimal.Parse(x.MaxRow.Field<string>("ValueAmount"))
    });

由于您使用了查询语法,在这种情况下,由于 let:

,它确实更具可读性
var newSort = from row in dtFinal.AsEnumerable()
  let xRow = new { Row = row, valueAmount = decimal.Parse(row.Field<string>("ValueAmount")) }
  group xRow by new
  {
     Substation = row.Field<string>("Substation"),
     ColumnTitle = row.Field<string>("ColumnTitle")
  } into grp
  let maxRow = grp.OrderByDescending(x => x.valueAmount).First()
  select new
  {
     ptime = maxRow.Row.Field<string>("ptime"),
     grp.Key.Substation,
     grp.Key.ColumnTitle,
     ValueAmount = maxRow.valueAmount
  };

这可以使用以下 2 个查询来实现:

var dt = from cu in DtFinals
         group cu.ValueAmount by new
            {
                cu.Substation,
                cu.ColumnTitle,
            } into gs
            select new
            {
                Substation = gs.Key.Substation,
                ColumnTitle = gs.Key.ColumnTitle,
                ValueAmount = gs.Max()
            };

var final = from c in DtFinals
            join d in dt on 
            new {c.Substation, c.ColumnTitle,c.ValueAmount} equals 
            new {d.Substation, d.ColumnTitle, d.ValueAmount}
            select new 
            { 
                ptime = c.Ptime, 
                Substation = d.Substation, 
                ColumnTitle = d.ColumnTitle,
                ValueAmount = d.ValueAmount
            };