2013-03-03 2 views
29

Я пытаюсь создать представление с предложением ORDER BY. У меня есть создать его успешно на SQL Server 2012 с пакетом обновления 1, но когда я пытаюсь воссоздать его на SQL Server 2008 R2, я получаю эту ошибку:Создать представление с предложением ORDER BY

Msg 102, Level 15, State 1, Procedure TopUsers, Line 11
Incorrect syntax near 'OFFSET'.

Код для создания представления является

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 

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

Это снимок экрана диаграммы

Я хочу, чтобы вернуть пользователям DisplayName d UserTotalMarks и закажите этот результат desc, так что пользователь с самым большим результатом будет на вершине.

+1

[К сожалению, «OFFSET» поддерживается только на SQL Server 2012] (http://msdn.microsoft.com/en-us/library/ms188385 (v = sql.110) .aspx) –

+2

OFFSET - это новое ключевое слово в SQL 2012 – Phil

+3

Просмотр не может быть отсортировано с предложением ORDER BY. Вы должны поместить предложение ORDER BY в любой запрос, который ссылается на представление. Результаты запросов упорядочиваются для отображения в клиентском приложении; строки в представлениях и таблицах неупорядочены. – sqlvogel

ответ

52

Я не уверен, что вы думаете об этом ORDER BY выполняет? Даже если вы сделаете, поместите ORDER BY в виде законным способом (например, добавив предложение TOP), если вы просто выберите из представления, например. SELECT * FROM dbo.TopUsersTest; без предложения ORDER BY, SQL Server может возвращать строки наиболее эффективным образом, что не обязательно соответствует ожидаемому порядку. Это связано с тем, что ORDER BY перегружен, поскольку он пытается выполнить две цели: сортировать результаты и определять, какие строки включать в TOP. В этом случае TOP всегда выигрывает (хотя в зависимости от индекса, выбранного для сканирования данных, вы можете заметить, что ваш заказ работает должным образом, но это просто совпадение).

Чтобы выполнить то, что вы хотите, вам нужно добавить предложение ORDER BY к запросам, которые извлекают данные из представления, а не коду самого представления.

Так ваш взгляд код должен быть просто:

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

ORDER BY не имеет смысла, так не должно быть даже включен.


Чтобы проиллюстрировать, используя AdventureWorks2012, вот пример:

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; 

Результаты:

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 

И вы можете увидеть из плана выполнения, что TOP и ORDER BY были абсолютно игнорируется и оптимизируется SQL Server:

enter image description here

Существует нет TOP оператора вообще, и нет. SQL Server полностью оптимизировал их.

Теперь, если вы измените представление, чтобы сказать ORDER BY SalesID, тогда вы просто получите заказ, который будет отображаться, но только - как упоминалось ранее - по совпадению.

Но если вы измените внешний запрос, чтобы выполнить ORDER BY вы хотели:

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

Вы получаете результаты упорядоченный так, как вы хотите:

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 

И план еще оптимизировала прочь TOP/ORDER BY на вид, но сортировка добавляется (за небольшую плату, заметьте), чтобы представить результаты, упорядоченные по CustomerID:

enter image description here

Итак, мораль истории, не ставьте ORDER BY в представлениях. Поместите ORDER BY в запросы, которые ссылаются на них. И если сортировка стоит дорого, вы можете рассмотреть возможность добавления/изменения индекса для его поддержки.

+1

Также для некоторых других фона: http://dba.stackexchange.com/a/21437/1186 –

+0

Я понимаю, почему в представлениях нет предложений ORDER BY, но я часто пишу Views как средство для хранения запроса, который я могу запустить вручную в SSMS или 'sqlcmd' /' osql' (например, отчеты), и я хочу, чтобы результаты были в каком-то порядке (обычно это некоторый столбец «date»), но по умолчанию они находятся в некотором неопределенном порядке. Было бы неплохо, если бы я мог хранить предложение ORDER BY по умолчанию в расширенном свойстве в представлении, которое SSMS автоматически добавляет, когда я выбираю «Сценарий SELECT» в Object Explorer. – Dai

+1

@Dai Возможно, вы должны сохранить свой запрос как хранимую процедуру вместо представления. –

3

Sql сервер дает нам исправление, чтобы мы могли создать представление с ORDER BY

здесь ссылка

Micorosft HotFix SQL Server

надеюсь, что это поможет.

+0

Ух, почему это еще не интегрировано в SQL Server 2012 !? –

+1

Неверная вещь, вероятно, эта сломанная ссылка. –

0

Ошибка: FROM (SELECT empno,name FROM table1 where location = 'A' ORDER BY emp_no)

И решение: FROM (SELECT empno,name FROM table1 where location = 'A') ORDER BY emp_no

24

я имел успех принуждая мнение заказывается с использованием

SELECT TOP 9999999 ... ORDER BY something 

К сожалению, с помощью SELECT TOP 100 PERCENT не работает из-за вопроса here ,

+2

Это работает! Спасибо! – LastTribunal

+0

Спасибо! BTW, 'TOP' принимает' bigint', поэтому я думаю, что это может быть еще больше. Таким образом, SSMS может отбросить этот порядок при запуске 'select top 1000' (ответ Аарона). однако удаление «ТОП 1000» из запроса еще более удобно, чем каждый раз вводить предложение «ORDER BY». –

-1

Просто используйте TOP 100 Percent в Select:

 CREATE VIEW [schema].[VIEWNAME] (
     [COLUMN1], 
     [COLUMN2], 
     [COLUMN3], 
     [COLUMN4]) 
    AS 
     SELECT TOP 100 PERCENT 
     alias.[COLUMN1], 
     alias.[COLUMN2], 
     alias.[COLUMN3], 
     alias.[COLUMN4] 
     FROM 
      [schema].[TABLENAME] AS alias 
      ORDER BY alias.COLUMN1 
    GO 
+2

Не нравится без комментариев: D Wow –

+0

Эти звезды в ** TOP 100 PERCENT ** неверный синтаксис: P – Klevi01

+0

Я попытался сделать исходный код ** TOP 100 PERCENT ** полужирный: D –

0

Пожалуйста, попробуйте ниже логику.

SELECT TOP(SELECT COUNT(SNO) From MyTable) * FROM bar WITH(NOLOCK) ORDER BY SNO 
-1

Для того, чтобы добавить ORDER BY в View Выполните следующие

CREATE VIEW [dbo].[SQLSTANDARDS_PSHH] 
AS 


SELECT TOP 99999999999999 
Column1, 
Column2 
FROM 
dbo.Table 
Order by 
Column1 
-1

Порядок использования

Создать ргос MyView в начинают ВЫБЕРИТЕ TOP 99999999999999 COLUMN1, COLUMN2 FROM dbo.Таблица Сортировать по COLUMN1 конца

выполнить процедуру

Exec MyView

0

С Sql 2012 Вы можете заставить порядок в представлениях и подзапросов с OFFSET

SELECT  C.CustomerID, 
      C.CustomerName, 
      C.CustomerAge 
FROM  dbo.Customer C 
ORDER BY CustomerAge OFFSET 0 ROWS; 

Внимание: это должно только для небольших списков, потому что OFFSET заставляет оценивать полный вид, даже если дополнительные соединения или фильтры вид уменьшает его размер!

Нет хорошего способа заставить заказ в представлении без побочного эффекта действительно и не без оснований.

Смежные вопросы