Подтвердить что ты не робот

Создать представление с предложением ORDER BY

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

Msg 102, уровень 15, состояние 1, процедура TopUsers, строка 11
Неправильный синтаксис около "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 и UserTotalMarks и заказать этот результат desc, поэтому пользователь с наибольшим результатом будет сверху.

4b9b3361

Ответ 1

Я не уверен, что вы думаете об этом 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 в запросы, ссылающиеся на них. И если сортировка стоит дорого, вы можете подумать о добавлении/изменении индекса для его поддержки.

Ответ 2

У меня был успех, заставляющий представление упорядочиваться с помощью

SELECT TOP 9999999 ... ORDER BY something

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

Ответ 3

Сервер Sql дает нам исправление, поэтому мы можем создать представление с ORDER BY

вот ссылка

Micorosft HotFix SQL Server

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

Ответ 4

Ошибка: 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

Ответ 5

Попробуйте приведенную ниже логику.

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

Ответ 6

Из Sql 2012 вы можете принудительно упорядочить в представлениях и подзапросах с помощью OFFSET

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

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

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

Ответ 7

Просто используйте 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

Ответ 8

Чтобы добавить ORDER BY в представление Выполните следующие

CREATE VIEW [dbo].[SQLSTANDARDS_PSHH]
AS


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

Ответ 9

используйте процедуру

Создать proc MyView в виде  начать SELECT TOP 99999999999999 Column1, Столбец2 ИЗ dbo.Table Сортировать по Column1 конец

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

exec MyView