Update: Please read the summary post of all the 11 Limitations of the view SQL SERVER – The Limitations of the Views – Eleven and more…
Recently, I was about the limitations of views. I started to make a list and realized that there are many limitations of the views. Let us start with the first well-known limitation.
Order By clause does not work in View. I agree with all of you who say that there is no need of using ORDER BY in the View. ORDER BY should be used outside the View and not in the View. This example is another reason why one should not use ORDER BY in Views.
Here is the quick example for the same. I have used sample database AdventureWorks for the example.
USE AdventureWorks
GO
-- First Run regular query and observe
SELECT *
FROM Sales.SalesOrderDetail
ORDER BY SalesOrderDetailID DESC
GO
-- Create view with same T-SQL Script
IF EXISTS (SELECT * FROM sys.views WHERE OBJECT_ID = OBJECT_ID(N'[dbo].[vw_ViewLimit1]'))
DROP VIEW [dbo].[vw_ViewLimit1]
GO
CREATE VIEW vw_ViewLimit1
AS
SELECT *
FROM Sales.SalesOrderDetail
ORDER BY SalesOrderDetailID DESC
GO
/*
Above Query will throw following error
Msg 1033, Level 15, State 1, Procedure vw_ViewLimit1, Line 5
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.
*/
-- Create view with same T-SQL Script without ORDER BY
IF EXISTS (SELECT * FROM sys.views WHERE OBJECT_ID = OBJECT_ID(N'[dbo].[vw_ViewLimit1]'))
DROP VIEW [dbo].[vw_ViewLimit1]
GO
CREATE VIEW vw_ViewLimit1
AS
SELECT *
FROM Sales.SalesOrderDetail
GO
-- Use Order by clause outside of the views
-- Create view with same T-SQL Script without ORDER BY
SELECT *
FROM vw_ViewLimit1
ORDER BY SalesOrderDetailID DESC
GO
If you try to include ORDER BY in View, it will throw the following error
Msg 1033, Level 15, State 1, Procedure vw_ViewLimit1, Line 5
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.
The above error itself explains how one can use ORDER BY in view. It suggests that if we use ORDER BY with TOP, we can surely use ORDER BY. If we want all the rows of the table, we can use TOP with 100 PERCENT. Let us try to modify our view with the usage of TOP 100 PERCENT and ORDER BY. This does not throw any error.
-- Create view with TOP 100 PERECENT and ORDER BY
IF EXISTS (SELECT * FROM sys.views WHERE OBJECT_ID = OBJECT_ID(N'[dbo].[vw_ViewLimit1]'))
DROP VIEW [dbo].[vw_ViewLimit1]
GO
CREATE VIEW vw_ViewLimit1
AS
SELECT TOP 100 PERCENT *
FROM Sales.SalesOrderDetail
ORDER BY SalesOrderDetailID DESC
GO
-- Select from view
SELECT *
FROM vw_ViewLimit1
GO
However, when you observe the resultset, you will notice that table is not ordered DESC, which is specified by SalesOrderDetailID column, as it should be. Let us examine the execution plan. You will not notice that there is no SORT operation at all.
I have heard many people talking about workaround, where they use some other number less than 100 in the TOP clause. Let us do a small test with 99.99 PERCENT and see the type of result we get.
-- Create view with TOP 99.99 PERECENT and ORDER BY
IF EXISTS (SELECT * FROM sys.views WHERE OBJECT_ID = OBJECT_ID(N'[dbo].[vw_ViewLimit1]'))
DROP VIEW [dbo].[vw_ViewLimit1]
GO
CREATE VIEW vw_ViewLimit1
AS
SELECT TOP 99.99 PERCENT *
FROM Sales.SalesOrderDetail
ORDER BY SalesOrderDetailID DESC
GO
-- Select from view
SELECT *
FROM vw_ViewLimit1
GO
Now let us check the result.We can clearly see that the result is Ordered by Column specified in the view.
However, as we are using TOP and 99.99, there is very little chance that we may not get all the rows from the table. Let us check the count of the rows in original table and Views.
-- Match the counts
SELECT COUNT(*) ViewCount
FROM vw_ViewLimit1
GO
SELECT COUNT(*) OriginalCount
FROM Sales.SalesOrderDetail
GO
From the count, it is clear that View has not returned all the rows because of the TOP specified. If table was a small table with less than 10,000 rows, this view might have not missed any rows, but in this case, where there are lots of rows, the View has missed rows.
Summary: It is not advisable to use ORDER BY in Views. Use ORDER BY outside the views. In fact, the correct design will imply the same. If you use TOP along with Views, there is a good chance that View will not return all the rows of the table or will ignore ORDER BY completely.
Please share your experience over here as comments.
Reference: Pinal Dave (https://blog.sqlauthority.com)
64 Comments. Leave new
hw can we use order by wid view????
whn i was givin d query in sql to make view thn i m getting error tht order by nt valid n cant b use wid view…..
Hi pinal,
can we find out script of a table using query. if possible then howwwwwwwwwww?
Thanks
Neelesh
What do you want to know about your table?
Try something like this:
DECLARE @schema_name sysname
DECLARE @table_name sysname
SELECT
c.name as [column_name],
typ.name as [type_name]
FROM
sys.schemas s
INNER JOIN sys.tables t ON s.schema_id = t.schema_id
INNER JOIN sys.columns c ON t.object_id = c.object_id
INNER JOIN sys.types typ ON c.user_type_id = typ.user_type_id
WHERE
s.name = @schema_name AND
t.name = @table_name
ORDER BY
c.column_id
It is not directly possible with a query. Try this procedure shown in this post
Nice Explanation dear Pinal
Very Good article.
Thanks,
Pinal
hi
If you want to use order by in view without using TOP clause use view with Schema
as
i have view from two table
CREATE VIEW vw_saggi
AS
SELECT dbo.Employees.FirstName, dbo.newt.LastName, dbo.Employees.EmployeeID
FROM dbo.First_table CROSS JOIN dbo.Second_table order by FirstName desc;
—–sort view using order by clause———————-
SELECT * from dbo.vw_saggi
order by FirstName desc;
———————————————————
try this
Satwinder Saggi
DBA
HI, i found your article very nice, and my friend and i suggest to create the view like this:
SELECT TOP (SELECT COUNT(*) FROM Sales.SalesOrderDetail) *
FROM Sales.SalesOrderDetail
ORDER BY SalesOrderDetailID DESC
And like that the result shows 100 percent of the rows.
Regards :)
In this case the correct method is
select top 100 percent * FROM Sales.SalesOrderDetail
ORDER BY SalesOrderDetailID DESC
That is nor correct as stated in the article when using 100 PERCENT, the ORDER BY clause is bypassed.
Thank you! I couldn’t figure out what I was doing wrong when my view sorted properly if I executed it in the “modify” window and not when when it was executed. You saved me a ton of time. I’ll sort in the stored procedure.
Good Article Sir..
Thanks for the article but I can’t agree that a bug in SQL can be treated as “well you shouldn’t do that anyway”. This IS a bug and has bee nresolved in a 2008 SP1. It also used to work fine in SQL 2000. There are many times you should be able to do this, for instance a view-on-a-view with an outer join and also with some third party reporting packages that require the data from a single view.
If it is not allowed then the view should NOT syntax check o.k. and be creatable.
It did not work for my for even 99 percent be work for 50 percent
I just wanted to let you know that this was a bug in versions of SQL Server after SQL Server 2000. There are hotfixes that take care of this issue.
https://support.microsoft.com/en-us/help/956717/cumulative-update-package-1-for-sql-server-2008/
https://support.microsoft.com/en-us/help/936305/
Thanks for the article. It really helped me understand why ORDER BY is not allowed inside a view.
Thanks,That’s great. i had same problem today. my view had a TOP 35000 in may Select statement. then it was working like order by clause. we have to omit TOP keyword from Views.
And this the first time I realize this issue.
SELECT *
FROM vw_AvailableLocations
WHERE UPC= ‘20612351’ AND Series= ‘00245’ — No returns
View Querry
SELECT Top 35000 INV.Item as Item ,INV.BinLoc as BinLoc,INV.Series as Supplier ,ISNULL((INV.Qty-ISNULL(ALLO.RQty,0)),INV.Qty) AS freeQty,INV.Qty as iQty
,UPC,Series
FROM DirectDATAINE5.dbo.WSL_InvLocation AS INV
LEFT JOIN (
SELECT szItem,szBinLoc ,ISNULL(SUM(iReqQty),0) AS RQty
FROM .dbo.tblAllocatedLocations
WHERE boolNUsed=0 AND boolCollected=0
GROUP BY szItem,szBinLoc
) AS ALLO
ON(ALLO.szItem COLLATE DATABASE_DEFAULT =INV.Item COLLATE DATABASE_DEFAULT AND ALLO.szBinLoc COLLATE DATABASE_DEFAULT =INV.BinLoc COLLATE DATABASE_DEFAULT )
LEFT JOIN (
SELECT ISNULL(1,0) AS Report,WL.szBinLoc,MA.szUPC,MA.szSeries FROM tblLocWsl AS WL
INNER JOIN dbo.tblJobsManifest AS MA
ON(MA.iUid=WL.iUID)
WHERE boolResolve = 0
) AS Rep
ON(INV.BinLoc COLLATE DATABASE_DEFAULT =Rep.szBinLoc COLLATE DATABASE_DEFAULT AND INV.Series COLLATE DATABASE_DEFAULT =Rep.szSeries COLLATE DATABASE_DEFAULT AND INV.UPC COLLATE DATABASE_DEFAULT =Rep.szUPC COLLATE DATABASE_DEFAULT)
WHERE INV.Qty>0 AND ISNULL((INV.Qty-ISNULL(ALLO.RQty,0)),INV.Qty)>0 –AND Modified>’2011-01-01 00:00:00.000′
–AND SUBSTRING (INV.BinLoc,1,1) = ‘A’
AND Report IS NULL AND UPC= ‘20612351’ AND Series= ‘00245’—-return Values
helpful
This resolved my issue:
CREATE VIEW vw_ViewLimit1
AS
SELECT TOP (select count(*) from Sales.SalesOrderDetail) *
FROM Sales.SalesOrderDetail
ORDER BY SalesOrderDetailID DESC
GO
— Select from view
SELECT *
FROM vw_ViewLimit1
GO
Muirhec
actually i need to confirm something.. whats the idea behind the hack of adding order by into the views query.. because as per my knowledge, while fetching data using views you can use order by in the query..
and if possible can someboday link me to the article of whats the use of views ? why its important and when its important ? because you can get the same result using query !!
as per my knowledge views are for sharing data with 3rd party or something but m not sure about it.. i have googled about this but i never found simple and easy to understand information on this with little example.. hope to get reply from Mr. Pinal on this..
thanks
hs
You can link directly to a view using say ODBC to return just a recordset without using a select query. In this case you may want the order in the view.
Well, I guess I am the black sheep in the discussion. First, I have been working with databases and SQL for over 25 years, going back to dBase. In all this time I have never seen any problem theoretically (not addressing any performance issues here) of using ORDER BY in views and philosophically I see nothing wrong with it if that is what the writer wants.
My philosophy is that I see views as a presentation of data (a way of viewing the data) which involves lower level processing of data, sometimes simple in nature, sometimes more complicated. Along these lines, I view the use of ORDER BY in views (in part) as a means of customer service so that a user of the view doesn’t have to understand internals to determine how to sort. For that matter, based on some of the discussion points previously mentioned, I could argue that the WHERE clause should also not be used in views…just let the user determine how they want to work the the data returned from the view. In real life I don’t support this and think WHERE clauses have a place in views, and in the same vein, so do ORDER BY clauses.
Also, sometimes I have wanted users to have a default view of something, which includes sorting. This comes in handy so I (and others) don’t have to take time to re-figure out how to sort the data each time we use the view for something. And views are useful (addressing a previous user’s question) because sometimes (when working with tools such as Access or InfoPath for example) complicated queries or SELECT statements cause problems and simplifying with a view is a slick and elegant solution.
So, while apparently I speak heresy according to some, I see nothing wrong with ORDER BY in views and was very annoyed and perplexed when I saw views which worked as expected in SQL 2000 not work in SQL 2008 when we [finally] upgraded.
BTW,
Microsoft apparently seems to think that using ORDER BY in views is valid. I just saw that they put out a fix for ORDER BY not working in views…
https://support.microsoft.com/en-us/help/926292/fix-when-you-query-through-a-view-that-uses-the-order-by-clause-in-sql
Don’t confuse “valid” for “too many people are using it”
Hello, great help this is.
I’m currently learning in this whole database thing.
I noticed that the order by does work in view. But ascending order only.
As I just try with small data, I think it still looks allright.
Can someone confirm this?
Thanks for this Article Pinal!!!!
Really Helped me a lot..