ORDER BY cümlesi ile bir görünüm oluşturma

Bir ORDER BY cümlesi ile bir görünüm oluşturmaya çalışıyorum. SQL Server 2012 SP1 üzerinde başarıyla oluşturdum, ancak SQL Server 2008 R2 üzerinde yeniden oluşturmaya çalıştığımda bu hatayı alıyorum:

Msg 102, Seviye 15, Durum 1, Prosedür TopUsers, Satır 11
Yanlış 'OFFSET' yakınındaki sözdizimi.

Görünümü oluşturmak için kod

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

=====================

Bu, diyagramın bir ekran görüntüsüdür

Kullanıcıların DisplayName ve UserTotalMarks değerlerini döndürmek ve bu sonucu desc olarak sıralamak istiyorum, böylece en büyük sonuca sahip kullanıcı en üstte olacak.

Çözüm

Bu ORDER BY'nin neyi başardığını düşündüğünüzden emin değilim? Görünüme yasal bir şekildeORDER BYkoysanız bile (örneğin birTOPcümlesi ekleyerek), görünümden sadece seçim yaparsanız, örneğinSELECT * FROM dbo.TopUsersTest;birORDER BYcümlesi olmadan, SQL Server satırları en verimli şekilde döndürmekte serbesttir, bu da beklediğiniz sırayla eşleşmeyebilir. Bunun nedeni,ORDER BYcümlesinin iki amaca hizmet etmeye çalıştığı için aşırı yüklenmiş olmasıdır: sonuçları sıralamak veTOPcümlesine hangi satırların dahil edileceğini belirlemek. Bu durumda,TOP` her zaman kazanır (verileri taramak için seçilen dizine bağlı olarak, sıralamanızın beklendiği gibi çalıştığını gözlemleyebilirsiniz - ancak bu sadece bir tesadüftür).

İstediğinizi elde etmek için, ORDER BY cümlesini görünümün kendi koduna değil, görünümden veri çeken sorgulara eklemeniz gerekir.

Yani görünüm kodunuz sadece şöyle olmalıdır:

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];

Sıralama ölçütü anlamsızdır, bu nedenle dahil edilmemelidir.


AdventureWorks2012 kullanarak açıklamak gerekirse, işte bir örnek:

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;

Sonuçlar:

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

Ve yürütme planından TOP ve ORDER BY ifadelerinin SQL Server tarafından kesinlikle göz ardı edildiğini ve optimize edildiğini görebilirsiniz:

Hiç TOP operatörü ve sıralama yoktur. SQL Server bunları tamamen optimize etmiştir.

Şimdi, görünümü ORDER BY SalesID olarak değiştirirseniz, görünümün belirttiği sıralamayı elde edersiniz, ancak yalnızca - daha önce de belirtildiği gibi - tesadüfen.

Ancak, istediğiniz ORDER BY işlemini gerçekleştirmek için dış sorgunuzu değiştirirseniz:

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

İstediğiniz şekilde sıralanmış sonuçlar elde edersiniz:

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

Ve plan hala görünümdeki TOP/ORDER BY öğelerini optimize etmiştir, ancak CustomerID öğesine göre sıralanmış sonuçları sunmak için bir sıralama eklenmiştir (küçük bir maliyet olmadan, dikkat edin):

Kıssadan hisse, görünümlere ORDER BY koymayın. Bunları referans alan sorgulara ORDER BY koyun. Ve sıralama pahalıysa, bunu desteklemek için bir dizin eklemeyi / değiştirmeyi düşünebilirsiniz.

Yorumlar (10)

kullanarak görünümü sıralanmaya zorlamakta başarılı oldum

SELECT TOP 9999999 ... ORDER BY something

Ne yazık ki SELECT TOP 100 PERCENT kullanmak burada sorunu nedeniyle çalışmıyor.

Yorumlar (2)

Hata şu: FROM (SELECT empno,name FROM table1 where location = 'A' ORDER BY emp_no)

Ve çözüm: FROM (SELECT empno,name FROM table1 where location = 'A') ORDER BY emp_no

Yorumlar (0)