从数据表中选择,由具有条件的多列分组

时间:2017-12-05 10:00:38

标签: c# visual-studio visual-studio-2010

我有一个数据表,里面有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。我怎么能这样做。

谢谢

2 个答案:

答案 0 :(得分:1)

您可以按此值降序排序以获取&#34; MaxRow&#34;,在那里找到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
  };

答案 1 :(得分:0)

这可以使用以下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
            };