Reputation: 1593
I'm looking to group records by their LeagueId
and Date
. Then order desc on the date and then select the first occurrence of a distinct LeagueId
. So far I have something like this but I don't know how to select stats in the first occurrence of a distinct LeagueId
.
var stats =
_statsRepository.FindBy(x => x.Active)
.GroupBy(x => new { x.LeagueId, x.Date })
.OrderByDescending(x => x.Key.Date)
.SelectMany(x => x);
Its pretty much a way to get the most recent stats per league. So League 1 = 12/02/2017 and league 2 could be 02/02/17. <--- disregard this, may be misleading.
There are many stat records that occur on a date in a league. So for a certain date with each league there would be multiple stats.
Record 1:
09/01/14,
Jim,
4 Goals,
League 1
Record 2:
13/01/14,
Jack,
2 Goals,
League 1
Record 3:
13/01/14,
James,
2 Goals,
League 1
Record 4:
15/01/14,
Hannah,
2 Goals,
League 2
Record 5:
15/01/14,
Harmony,
1 Goal,
League 2
Record 6:
10/01/14,
Alision,
3 Goals,
League 2
The records that should be selected are
Record 2:
13/01/14,
Jack,
2 Goals,
League 1
Record 3:
13/01/14,
James,
2 Goals,
League 1
Record 4:
15/01/14,
Hannah,
2 Goals,
League 2
Record 5:
15/01/14,
Harmony,
1 Goal,
League 2
Explanation: For league 1 Records 2 & 3 occurs later than record 1 so they are both selected. For league 2 records 4 & 5 should be selected as they are the latest date.
Upvotes: 2
Views: 10411
Reputation: 205849
With the latest update, you need to group by LeagueId
and simply get all the records from each grouping with Date
equals max Date
in the grouping:
var stats = _statsRepository.FindBy(x => x.Active)
.GroupBy(x => x.LeagueId)
.SelectMany(g => g.Where(x => x.Date == g.Max(y => y.Date));
Another way to get the same result is to use !Any
(SQL NOT EXISTS
) construct:
var baseStats = _statsRepository.FindBy(x => x.Active);
var stats = baseStats
.Where(x => !baseStats.Any(y => y.LeagueId == x.LeagueId && y.Date > x.Date));
I assume you work with IQueryable
s (i.e. not LINQ to Objects where such things matter), so no optimizations like intermediate Select
s are needed.
Upvotes: 5
Reputation: 247551
You want to group by league then take the most recent date in the group for each league
var stats = _statsRepository.FindBy(x => x.Active)
.GroupBy(x => new { x.LeagueId, x.Date })
.GroupBy(g => g.Key.LeagueId)
.Select(gg => new { LeagueId = gg.Key, Stats = gg.OrderByDescending(g => g.Key.Date).First().ToList() })
.ToList();
Upvotes: 1