Question : sorting in views

I created a view in the AdventureWorks db, showing the contact names.  I then specified an ascending sort on the name column.  All works exactly as expected.

Now I save and close the view.  I then "Open View" to once again see the output.  The names are no longer sorted properly, as if it's completely ignoring my sort setting.  What's going on???

gary

Answer : sorting in views

In theory view is a virtual table. So it has no specyfic order. If you need your results ordered add order by clause out of the view. Sometimes however you "MUST" use order by inside a view because database software you use allow you for specyfying the view name but not order by clause.

There is, some workaround to this problem. If also specyfy TOP clause ORDER BY starts working as a filter, because the order determines which row will be returned or not. But how to return all rows and sill maintain the order? The answer is (or was) TOP 100 PERCENT. Top is added so you can also use order by. And it worked well in SQL 2000. Now with SQL 2005 guys from MS realized that TOP 100 PERCENT is not really a filter. So they allow for syntax, but eliminate both TOP and ORDER BY from operators from execution plans. However there are still some workarounds to this "fix".

1. Instead of using TOP 100 PERCENT, use TOP 99.999999999999 PERCENT, or TOP 100000000000000.
Of course there is a possibility to return not all rows, but the table should have laaaarge number of rows. So it works in majority of cases. What is more, MS himself uses this workaround in Migration Assistant from Access to SQL Server when converting access queries to views :)

2. Add a ranking function like row number and specify desired order in over() clause. Because SQL Server have to sort the table to compute row_number, sorted resultset is the easyiest to return. But remember: you MUST SPECIFY rownumber column in select clause and it must be the last column computed by ranking function returned.

WARINING! Views with order by work well if you use them directly from your application for simple selecting data. NEVER try to join them with other tables/views, because their performance is often horrible then.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
-- first workaround
GO
create view dbo.vPersonContactOrdered
as
select top 99.99999999999 percent * from Person.Contact
order by firstname, lastname
GO
select * from dbo.vPersonContactOrdered -- it works
GO
create view dbo.vPersonContactOrdered2
as
select *, row_number() over (order by firstname, lastname) as rownumber from Person.Contact
GO
select * from dbo.vPersonContactOrdered2 -- it also works
GO
Random Solutions  
 
programming4us programming4us