SQL SERVER – ORDER BY Does Not Work – Limitation of the Views Part 1

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.

SQL SERVER – ORDER BY Does Not Work – Limitation of the Views Part 1 ViewLimit1

SQL SERVER – ORDER BY Does Not Work – Limitation of the Views Part 1 ViewLimit2

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.

SQL SERVER – ORDER BY Does Not Work – Limitation of the Views Part 1 ViewLimit3

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.

SQL SERVER – ORDER BY Does Not Work – Limitation of the Views Part 1 ViewLimit4

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)

SQL Scripts, SQL View
Previous Post
SQL SERVER – Computed Columns – Index and Performance
Next Post
SQLAuthority News – Feedback Received for Virtual Tech Days Sessions on Spatial Database

Related Posts

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…..

    Reply
  • Hi pinal,

    can we find out script of a table using query. if possible then howwwwwwwwwww?

    Thanks

    Neelesh

    Reply
    • 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

      Reply
    • It is not directly possible with a query. Try this procedure shown in this post

      Reply
  • Nice Explanation dear Pinal

    Reply
  • Very Good article.

    Thanks,
    Pinal

    Reply
  • 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

    Reply
  • 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 :)

    Reply
    • In this case the correct method is

      select top 100 percent * FROM Sales.SalesOrderDetail
      ORDER BY SalesOrderDetailID DESC

      Reply
      • 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.

    Reply
  • Good Article Sir..

    Reply
  • 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.

    Reply
  • It did not work for my for even 99 percent be work for 50 percent

    Reply
  • 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/

    Reply
  • Thanks for the article. It really helped me understand why ORDER BY is not allowed inside a view.

    Reply
  • 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

    Reply
  • helpful

    Reply
  • 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

    Reply
  • 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

    Reply
    • 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.

      Reply
  • colson.anthony@scrippshealth.org
    March 28, 2013 1:44 am

    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.

    Reply
  • colson.anthony@scrippshealth.org
    March 28, 2013 1:51 am

    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

    Reply
  • 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?

    Reply
  • Abhishek Yadav
    July 26, 2013 12:32 am

    Thanks for this Article Pinal!!!!
    Really Helped me a lot..

    Reply

Leave a Reply