I seem to have the simplest problem but can't seem to get it right. I have a SQL table which looks something like this:
Code | Period | PeriodVersion | SourceId
Foo 201810 1 Source1
Foo 201810 2 Source1
Foo 201811 1 Source1
Bar 201810 1 Source1
Foo 201809 2 Source1
Foo 201809 1 Source1
Foo 201808 1 Source1
The query has the following requirements:
Period
should be grouped by 201809, 201810 and 201811 and only the highestPeriodVersion
should be returned. (in some cases there are 6 periods as well)Code
should be equal to FooSourceId
should be equal to Source1
If all works well I would like to have the following result:
Code | Period | PeriodVersion | SourceId
Foo 201810 2 Source1
Foo 201811 1 Source1
Foo 201809 2 Source1
I've tried the following:
var query = from item in context.MyTable
orderby item.PeriodVersion descending
where item .Code== item.ISINCode &&
item .SourceID == "Source1" &&
(
"201810" == item.Period ||
"201811" == item.Period ||
"201819 == item.Period
)
group item by item.Period into g
select g.FirstOrDefault();
It translates to:
SELECT * // Selected columns here....
FROM [MyTable] AS [table]
WHERE ((([table].[Code] = 'Foo') AND ([table].[SourceID] = 'Source1'))) AND [table].[Period] IN ('201209', '201208', '201207')
ORDER BY [table].[Period], [table].[PeriodVersion] DESC
This will return the "correct" results, but it executes the groupby in memory which fetches all PeriodVersion
from the database. In some cases I have >50 PeriodVersion
for each Period
which makes the query above very inefficient. Is there any way to make this more efficient?
I have also tried this based on this answer:
var query = context.MyTable
.GroupBy(x => x.Period)
.Select(g => g
.OrderByDescending(p =>
p.PeriodVersion
).FirstOrDefault(x => x.Code == "Foo" &&
x.SourceID == "Source1" &&
(
"201810" == item .Period ||
"201811" == item .Period ||
"201819 == item .Period
)
);
It gave an even worse result since it did execute the where
in memory.
Select *
FROM MyTable AS [x]
ORDER BY [x].[Period]
My actual table has a lot more columns than the ones listed here. I'm using EF Core 2.1. I can upgrade to a newer version but it would require some major overhaul. According to the documentation groupby is supported. But when reading about it here on SO it seems to be tricky.