Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ - Select Records with Max Property Value per Group

I've got a data set like this:

GroupName   GroupValue   MemberName   MemberValue
'Group1'    1            'Member1'    1
'Group1'    1            'Member2'    2
'Group2'    2            'Member3'    3
'Group2'    2            'Member4'    2
'Group3'    2            'Member5'    4
'Group3'    2            'Member6'    1

What I want to select is the rows that have the maximum MemberValue per GroupName, but only for those GroupNames that have the largest GroupValue, and pass them into a delegate function. Like this:

'Group2'    2            'Member3'    3
'Group3'    2            'Member5'    4

So far I've tried this format...

data.Where(maxGroupValue => 
    maxGroupValue.GroupValue == data.Max(groupValue => groupValue.GroupValue))
.Select(FunctionThatTakesData)

...but that just gives me every member of Group2 and Group3. I've tried putting a GroupBy() before the Select(), but that turns the output into an IGrouping<string, DataType> so FunctionThatTakesData() doesn't know what to do with it, and I can't do another Where() to filter out only the maximum MemberValues.

What can I do to get this data set properly filtered and passed into my function?

like image 286
JAF Avatar asked May 05 '17 12:05

JAF


People also ask

How do you select records with Max ID that group by multiple columns in LINQ to SQL?

In SQL, it is very simple to do: SELECT * FROM [dbo]. [tblOrderDeliveryGroup] t1 WHERE [DeliveryGroupId] IN ( SELECT MAX([DeliveryGroupId]) FROM [dbo]. [tblOrderDeliveryGroup] t2 WHERE (t1.

How do you select the record with the highest date in Linq?

MaxBy() is now . MaxBy(). First() . This has the advantage that you can handle more than 1 result (used to be only the first person with the max age, but there may be more persons with the same age).

How do you find the maximum value in Linq?

In LINQ, you can find the maximum element of the given sequence by using Max() function. This method provides the maximum element of the given set of values. It does not support query syntax in C#, but it supports in VB.NET. It is available in both Enumerable and Queryable classes in C#.


1 Answers

You can do that with the following Linq.

var results = data.GroupBy(r = r.GroupValue)
    .OrderByDescending(g => g.Key)
    .FirstOrDefault()
    ?.GroupBy(r => r.GroupName)
    .Select(g => g.OrderByDescending(r => r.MemberValue).First());

First you have to group on the GroupValue then order the groups in descending order by the Key (which is the GroupValue) and take the first one. Now you have all the rows with the max GroupValue. Then you group those on the GroupName and from those groups order the MemberValue in descending order and take the First row to get the row in each GroupName group with the max MemberValue. Also I'm using the C# 6 null conditional operator ?. after FirstOrDefault in case data is empty. If you're not using C# 6 then you'll need to handle that case up front and you can just use First instead.

like image 103
juharr Avatar answered Oct 08 '22 23:10

juharr