I'm trying to create a view with an ORDER BY
clause. I have create it successfully on SQL Server 2012 SP1, but when I try to re-create it on SQL Server 2008 R2, I get this error:
Msg 102, Level 15, State 1, Procedure TopUsers, Line 11
Incorrect syntax near 'OFFSET'.
The code to create the view is
CREATE View [dbo].[TopUsersTest]
as
select
u.[DisplayName] , sum(a.AnswerMark) as Marks
From Users_Questions us inner join [dbo].[Users] u
on u.[UserID] = us.[UserID]
inner join [dbo].[Answers] a
on a.[AnswerID] = us.[AnswerID]
group by [DisplayName]
order by Marks desc
OFFSET 0 ROWS
=====================
This is a screen shot of the diagram
I wish to return users' DisplayName
and the UserTotalMarks
and order this result desc, so the user with the biggest result with be on the top.
Just use TOP 100 Percent in the Select:
In order to add an ORDER BY to a View Perform the following
I'm not sure what you think this
ORDER BY
is accomplishing? Even if you do putORDER BY
in the view in a legal way (e.g. by adding aTOP
clause), if you just select from the view, e.g.SELECT * FROM dbo.TopUsersTest;
without anORDER BY
clause, SQL Server is free to return the rows in the most efficient way, which won't necessarily match the order you expect. This is becauseORDER BY
is overloaded, in that it tries to serve two purposes: to sort the results and to dictate which rows to include inTOP
. In this case,TOP
always wins (though depending on the index chosen to scan the data, you might observe that your order is working as expected - but this is just a coincidence).In order to accomplish what you want, you need to add your
ORDER BY
clause to the queries that pull data from the view, not to the code of the view itself.So your view code should just be:
The
ORDER BY
is meaningless so should not even be included.To illustrate, using AdventureWorks2012, here is an example:
Results:
And you can see from the execution plan that the
TOP
andORDER BY
have been absolutely ignored and optimized away by SQL Server:There is no
TOP
operator at all, and no sort. SQL Server has optimized them away completely.Now, if you change the view to say
ORDER BY SalesID
, you will then just happen to get the ordering that the view states, but only - as mentioned before - by coincidence.But if you change your outer query to perform the
ORDER BY
you wanted:You get the results ordered the way you want:
And the plan still has optimized away the
TOP
/ORDER BY
in the view, but a sort is added (at no small cost, mind you) to present the results ordered byCustomerID
:So, moral of the story, do not put ORDER BY in views. Put ORDER BY in the queries that reference them. And if the sorting is expensive, you might consider adding/changing an index to support it.
use Procedure
Create proc MyView as begin SELECT TOP 99999999999999 Column1, Column2 FROM dbo.Table Order by Column1 end
execute procedure
exec MyView
From Sql 2012 you can force ordering in views and subqueries with OFFSET
Warning: this should only be used on small lists because OFFSET forces the full view to be evaluated even if further joins or filters on the view reduce its size!
There is no good way to force ordering in a view without a side effect really and for good reason.
Please try the below logic.