2010-09-03 46 views
3

我有一个表,看起来像这样:LINQ到SQL组通过采取

Id GroupId Value 

,它有大约100行

我怎样才能返回前10行的价值,但没有复制GroupId的?

回答

3

这应做到:

var results = table 
    .GroupBy(x => x.GroupId) 
    .Select(x => new { Row = x, Value = x.Max(y => y.Value) }) 
    .OrderByDescending(x => x.Value) 
    .Select(x => x.Row) 
    .Take(10); 

编辑:修改返回整个对象。

+0

怎么是这种表现?这将生成一个纯粹的SQL解决方案吗?只是不想返回整个表,然后处理结果在c# – Taho 2010-09-03 01:42:47

+0

请注意,这只返回*值*的列表,而不是全行数据。我*想*他想要整行的最高值。 – 2010-09-03 01:44:16

+0

我确实需要整行。 – Taho 2010-09-03 01:59:05

0

不知道这是否转换为LINQ到SQL,但这里是从L2Obj

var query = (from foo in foos 
       group foo by foo.GroupId into fg 
       select fg.OrderByDescending(f => f.Value).First()) 
       .OrderByDescending(f => f.Value) 
       .Take(10); 

英语的想法,这组在groupId和具有最高价值从各组选择符,如果有的话,你可以从L2SQL获得你的对象的具体列表,然后在内存中执行分组,不应该是性能/内存问题,因为你说只有100行。

对于LINQ到SQL,你可能尝试这样

var sqlQuery = (from foo in foos 
       join y in 
        (from f2 in foos 
         join x in 
          (from f1 in foos 
          group f1 by f1.GroupId into vg 
          select new { GroupId = vg.Key, MaxVal = vg.Max(f => f.Value) }) 
          on f2.GroupId equals x.GroupId 
         where f2.Value == x.MaxVal 
         group f2 by f2.GroupId into mg 
         select new { GroupId = mg.Key, MinId = mg.Min(f => f.Id) }) 
       on foo.Id equals y.MinId 
       orderby foo.Value descending 
       select foo).Take(10); 

这东西是基于SQL查询来执行相同的操作

Select top 10 f.* 
From Foos f 
Inner Join 
(Select f.GroupID, min(f.Id) as MinId 
From Foos f 
Inner Join 
(Select GroupId, Max(Value) as MaxVal 
From Foos 
Group By GroupId) x 
on f.GroupId = x.GroupId 
and f.Value = x.MaxVal 
Group By f.GroupId) y 
on f.Id = y.MinId 
order by f.Value desc 

它基本上执行两个分组。第一个获取每个组的最大值,第二个获取每个组中具有最大值的每个记录的最小ID(如果组中的2个记录具有相同的值),然后选择前10个记录。

1

这人会得到充分的行值(它的工作对我来说与样本数据我告诉波纹管):

static void Main(string[] args) 
{ 
    Whatever one = new Whatever() {GroupId = 1, Id = 1, Value = 2}; 
    Whatever two = new Whatever() { GroupId = 1, Id = 2, Value = 8 }; 
    Whatever three = new Whatever() { GroupId = 2, Id = 3, Value = 16 }; 
    Whatever four = new Whatever() { GroupId = 2, Id = 4, Value = 7 }; 
    Whatever five = new Whatever() { GroupId = 3, Id = 5, Value = 21 }; 
    Whatever six = new Whatever() { GroupId = 3, Id = 6, Value = 12 }; 
    Whatever seven = new Whatever() { GroupId = 4, Id = 7, Value = 5 }; 
    Whatever eight = new Whatever() { GroupId = 5, Id = 8, Value = 17 }; 
    Whatever nine = new Whatever() { GroupId = 6, Id = 9, Value = 13 }; 
    Whatever ten = new Whatever() { GroupId = 7, Id = 10, Value = 44 }; 

    List<Whatever> list = new List<Whatever>(); 
    list.Add(one); 
    list.Add(two); 
    list.Add(three); 
    list.Add(four); 
    list.Add(five); 
    list.Add(six); 
    list.Add(seven); 
    list.Add(eight); 
    list.Add(nine); 
    list.Add(ten); 

    var results = (from w in list 
        group w by w.GroupId into g 
        select new { GroupId = g.Key, 
           Value = g.Max(w => w.Value), 
           Id = g.OrderBy(w=>w.Value).Last().Id }). 
        OrderByDescending(w=>w.Value).Take(5); 

    foreach (var r in results) 
    { 
     Console.WriteLine("GroupId = {0}, 
          Id = {1}, 
          Value = {2}", 
          r.GroupId, r.Id, r.Value); 
    } 

} 

输出:

GroupId = 7, Id = 10, Value = 44 
GroupId = 3, Id = 5, Value = 21 
GroupId = 5, Id = 8, Value = 17 
GroupId = 2, Id = 3, Value = 16 
GroupId = 6, Id = 9, Value = 13