-
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
SQLException : Incorrect syntax near the keyword 'UNION' #18362
Comments
First, as a workaround use client evaluation (since the operation is a UNION there's little difference): _context.Subjects.Where(s => !(s is Group))
.OrderBy(o => o.Created)
.Take(10)
.AsEnumerable()
.Union(_context.Subjects.Where(s => s is Group)
.OrderBy(o => o.Created)
.Take(10)
.AsEnumerable())
.ToList(); SQL Server and Sqlite don't support ORDER BY inside set operation clauses (PostgreSQL does but requires parentheses around the clause). Sqlite does allow ORDER BY in subqueries so we could push down: SELECT * FROM (SELECT 1 AS x ORDER BY x LIMIT 1) UNION SELECT 2;
Note that regardless, Sqlite also doesn't support LIMIT/OFFSET in the clause, SQL Server allows TOP but not LIMIT/OFFSET (because no ORDER BY). PostgreSQL again supports everything as long as the clause is surrounded by parentheses. |
The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP or FOR XML is also specified I specified Take(x) that translate to top(x), so i don't want two query, instead of 1 with union on Server |
ORDER BY isn't supported in set operation clauses regardless of whether TOP is specified or not. For example, the following fails while the same thing without the ORDER BY works: SELECT TOP(1) 1 AS x ORDER BY x UNION SELECT 2; |
Can you translate to this: |
Apologies, I mistested the above - in SQL Server ORDER BY is of course OK in subqueries as long as TOP is present as well. So it's indeed possible to translate this by pushing down to a subquery in the SQL Server and Sqlite case (again, in the PostgreSQL case an actual subquery isn't necessary, only parentheses). |
Test: [ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task OrderBy_Take_Union(bool isAsync)
{
return AssertQuery(
isAsync, ss => ss.Set<Customer>()
.OrderBy(c => c.ContactName)
.Take(1)
.Union(ss.Set<Customer>()
.OrderBy(c => c.ContactName)
.Take(1)),
entryCount: 1,
assertOrder: true);
} |
SELECT TOP(1) [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region]
FROM [Customers] AS [c]
ORDER BY [c].[ContactName]
UNION
SELECT TOP(1) [c0].[CustomerID], [c0].[Address], [c0].[City], [c0].[CompanyName], [c0].[ContactName], [c0].[ContactTitle], [c0].[Country], [c0].[Fax], [c0].[Phone], [c0].[PostalCode], [c0].[Region]
FROM [Customers] AS [c0]
ORDER BY [c0].[ContactName] Above is invalid SQL but when you push down the whole thing it's valid. SELECT *
FROM (
SELECT TOP(1) [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region]
FROM [Customers] AS [c]
ORDER BY [c].[ContactName]
UNION
SELECT TOP(1) [c0].[CustomerID], [c0].[Address], [c0].[City], [c0].[CompanyName], [c0].[ContactName], [c0].[ContactTitle], [c0].[Country], [c0].[Fax], [c0].[Phone], [c0].[PostalCode], [c0].[Region]
FROM [Customers] AS [c0]
ORDER BY [c0].[ContactName]
) as t |
Linq query with Union and OrderBy does not translate correctly.
Simple:
This will be translate to =>
Incorrect syntax near the keyword 'UNION'
EF Core version:
Database provider: (e.g. Microsoft.EntityFrameworkCore.SqlServer)
Target framework: (e.g. .NET Core 3.0)
Operating system:
IDE: (e.g. Visual Studio 2019 16.3)
The text was updated successfully, but these errors were encountered: