-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Query: GroupBy scalar subquery generates invalid SQL #19027
Comments
|
In a meanwhile, until we got a fix, there is a temporary solution. I built extension method ApplySubQuery to include subquery with APPLY operators, and it also solve case GROUP BY + SubQuery. Using that approach, I'm finally able to use the columns from subquery in GroupBy clause, which is one of the "fundamental" issue of EF Core. EF Core dupplicates the subquery 'statement' into another clauses as WHERE, which can also have negative affects on performance or doesn't work at all (in GroupBy case). And it's happening constantly with EF Core. Thats why I said that is a fundamental issue. Standard Linq, non-working await _dbContext
.Patients
.Select(x => new
{
x.ClinicCreatedId,
ConfirmationDate = _dbContext.Appointments
.Where(y => y.PatientId == x.Id)
.OrderByDescending(y => y.ConfirmationDate)
.Select(x => x.ConfirmationDate)
.FirstOrDefault()
})
.GroupBy(x => new { x.ClinicCreatedId, x.ConfirmationDate })
.Select(x => new
{
x.Key.ClinicCreatedId,
x.Key.ConfirmationDate,
PatientCount = x.Count()
})
.ToListAsync(); it's produced invalid SQL SELECT [p].[ClinicCreatedId], (
SELECT TOP(1) [a].[ConfirmationDate]
FROM [dbo].[Appointments] AS [a]
WHERE [a].[PatientId] = [p].[Id]
ORDER BY [a].[ConfirmationDate] DESC) AS [ConfirmationDate], COUNT(*) AS [PatientCount]
FROM [dbo].[Patients] AS [p]
GROUP BY [p].[ClinicCreatedId], (
SELECT TOP(1) [a].[ConfirmationDate]
FROM [dbo].[Appointments] AS [a]
WHERE [a].[PatientId] = [p].[Id]
ORDER BY [a].[ConfirmationDate] DESC) Here the working example: await _dbContext
.Patients
.ApplySubQuery(x => _dbContext.Appointments.Where(y => y.PatientId == x.Id).OrderByDescending(y => y.ConfirmationDate).Take(1))
.Select(x => new
{
x.Outer.ClinicCreatedId,
x.Inner.ConfirmationDate
})
.GroupBy(x => new { x.ClinicCreatedId, x.ConfirmationDate })
.Select(x => new
{
x.Key.ClinicCreatedId,
x.Key.ConfirmationDate,
PatientCount = x.Count()
})
.ToListAsync(); SELECT [p].[ClinicCreatedId], [t0].[ConfirmationDate], COUNT(*) AS [PatientCount]
FROM [dbo].[Patients] AS [p]
CROSS APPLY (
SELECT [t].*
FROM (
SELECT TOP(1) [a].*
FROM [dbo].[Appointments] AS [a]
WHERE [a].[PatientId] = [p].[Id]
ORDER BY [a].[ConfirmationDate] DESC
) AS [t]
WHERE CAST(1 AS bit) = CAST(1 AS bit)
) AS [t0]
GROUP BY [p].[ClinicCreatedId], [t0].[ConfirmationDate] |
Also generates the following error in MySQL with
SELECT (
SELECT `c`.`ContactName`
FROM `Customers` AS `c`
WHERE `c`.`CustomerID` = `o`.`CustomerID`
LIMIT 1) AS `Key`, COUNT(*) AS `Count`
FROM `Orders` AS `o`
GROUP BY (
SELECT `c`.`ContactName`
FROM `Customers` AS `c`
WHERE `c`.`CustomerID` = `o`.`CustomerID`
LIMIT 1) Works fine however, if |
* Remove remnants of workaround for dotnet/efcore#25127. * Remove workaround for dotnet/efcore#24819. * Remove workaround for dotnet/efcore#24806. * Remove workaround for dotnet/efcore#19027.
Generates SQL
Throws
Passes for InMemory/Sqlite
The text was updated successfully, but these errors were encountered: