Wrong generated SQL for SQL Server 2012/2014 (DISTINCT / OFFSET)
See original GitHub issueI am using this provider:
SqlServerDataProvider(ProviderName.SqlServer2012, SqlServerVersion.v2012);
Which produces the following SQL query (simplified for demo):
exec sp_executesql N'SELECT DISTINCT
[test].[Id]
FROM
[dbo].[Test] [test]
ORDER BY
[test].[Time] DESC,
[test].[Id] DESC
OFFSET 0 ROWS FETCH NEXT 60 ROWS ONLY'
But it is not valid SQL: “ORDER BY items must appear in the select list if SELECT DISTINCT is specified.”
Linq:
var query = from test in storage.Tests
orderby test.Time descending, test.Id descending
select test.Id;
var tests = query.Distinct().Page(page, size).ToList();
Internally Page method uses Skip and Take to get desired page.
When I am using 2008 provider, it generates ROW_NUMBER and all works fine:
exec sp_executesql N'SELECT *
FROM
(
SELECT
t.*,
ROW_NUMBER() OVER
(
ORDER BY
oby DESC,
oby1 DESC
) as rn
FROM
(
SELECT DISTINCT
[test].[Id],
[test].[Time] as [oby],
[test].[Id] as [oby1]
FROM
[dbo].[Test] [test]
) t
) t1
WHERE
t1.rn BETWEEN 1 AND 60'
In this specific case (when Id of table is used) I can implement workaround by including Time in query and by wrapping offset query with Id selection. But it is only possible because (Id, Time) will be always unique due to Id. But in common scenario there are no way to order rows and select page if ordering columns are not targets in query.
So it is not good that something can work for SQL Server 2008 and cannot work for 2012/2014 one.
Issue Analytics
- State:
- Created 7 years ago
- Comments:20 (13 by maintainers)
@ili, it is not equivalent queries. You’ve missed proper ordering by Time in result query.
Fixed by #1221