Create a view with ORDER BY clause

前端 未结 9 1495
轻奢々
轻奢々 2020-11-30 04:42

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

相关标签:
9条回答
  • 2020-11-30 05:12

    In order to add an ORDER BY to a View Perform the following

    CREATE VIEW [dbo].[SQLSTANDARDS_PSHH]
    AS
    
    
    SELECT TOP 99999999999999
    Column1,
    Column2
    FROM
    dbo.Table
    Order by
    Column1
    
    0 讨论(0)
  • 2020-11-30 05:13

    I'm not sure what you think this ORDER BY is accomplishing? Even if you do put ORDER BY in the view in a legal way (e.g. by adding a TOP clause), if you just select from the view, e.g. SELECT * FROM dbo.TopUsersTest; without an ORDER 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 because ORDER BY is overloaded, in that it tries to serve two purposes: to sort the results and to dictate which rows to include in TOP. 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:

    CREATE VIEW [dbo].[TopUsersTest] 
    AS 
      SELECT 
        u.[DisplayName], SUM(a.AnswerMark) AS Marks
      FROM
        dbo.Users_Questions AS uq
        INNER JOIN [dbo].[Users] AS u
          ON u.[UserID] = us.[UserID] 
        INNER JOIN [dbo].[Answers] AS a
          ON a.[AnswerID] = uq.[AnswerID]
        GROUP BY u.[DisplayName];
    

    The ORDER BY is meaningless so should not even be included.


    To illustrate, using AdventureWorks2012, here is an example:

    CREATE VIEW dbo.SillyView
    AS
      SELECT TOP 100 PERCENT 
        SalesOrderID, OrderDate, CustomerID , AccountNumber, TotalDue
      FROM Sales.SalesOrderHeader
      ORDER BY CustomerID;
    GO
    
    SELECT SalesOrderID, OrderDate, CustomerID, AccountNumber, TotalDue
    FROM dbo.SillyView;
    

    Results:

    SalesOrderID   OrderDate   CustomerID   AccountNumber   TotalDue
    ------------   ----------  ----------   --------------  ----------
    43659          2005-07-01  29825        10-4020-000676  23153.2339
    43660          2005-07-01  29672        10-4020-000117  1457.3288
    43661          2005-07-01  29734        10-4020-000442  36865.8012
    43662          2005-07-01  29994        10-4020-000227  32474.9324
    43663          2005-07-01  29565        10-4020-000510  472.3108
    

    And you can see from the execution plan that the TOP and ORDER BY have been absolutely ignored and optimized away by SQL Server:

    enter image description here

    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:

    SELECT SalesOrderID, OrderDate, CustomerID, AccountNumber, TotalDue
    FROM dbo.SillyView
    ORDER BY CustomerID;
    

    You get the results ordered the way you want:

    SalesOrderID   OrderDate   CustomerID   AccountNumber   TotalDue
    ------------   ----------  ----------   --------------  ----------
    43793          2005-07-22  11000        10-4030-011000  3756.989
    51522          2007-07-22  11000        10-4030-011000  2587.8769
    57418          2007-11-04  11000        10-4030-011000  2770.2682
    51493          2007-07-20  11001        10-4030-011001  2674.0227
    43767          2005-07-18  11001        10-4030-011001  3729.364
    

    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 by CustomerID:

    enter image description here

    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.

    0 讨论(0)
  • 2020-11-30 05:20

    I've had success forcing the view to be ordered using

    SELECT TOP 9999999 ... ORDER BY something
    

    Unfortunately using SELECT TOP 100 PERCENT does not work due the issue here.

    0 讨论(0)
提交回复
热议问题