52

ORDER BY句付きのビューを作成しようとしています。SQL Server 2012 SP1で正常に作成しましたが、SQL Server 2008 R2で再作成しようとすると、次のエラーが発生します。

メッセージ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、この結果の説明を注文したいので、結果が最も大きいユーザーが一番上になります。

4

9 に答える 9

88

ORDER BYこれが何を成し遂げていると思うかわかりませんか?正当な方法で(たとえば、句を追加することによって)ビューに配置した場合でもたとえば句なしでビューから選択した場合、SQLServerは最も効率的な方法で行を自由に返すことができます。必ずしも期待する順序と一致します。これは、がオーバーロードされているためです。つまり、結果を並べ替える目的と、に含める行を指定する目的の2つを提供しようとします。この場合、常に勝ちます(ただし、データをスキャンするために選択したインデックスによっては、注文が期待どおりに機能していることがわかりますが、これは単なる偶然です)。ORDER BYTOPSELECT * FROM dbo.TopUsersTest;ORDER BYORDER BYTOPTOP

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

また、実行プランから、TOPORDER BYがSQL Serverによって完全に無視され、最適化されていることがわかります。

ここに画像の説明を入力してください

TOP演算子はまったくなく、並べ替えもありません。SQLServerはそれらを完全に最適化しました。

ここで、ビューを「」に変更すると、ビューに示されて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

ここに画像の説明を入力してください

したがって、話の教訓は、ビューにORDERBYを入れないことです。それらを参照するクエリにORDERBYを入れます。また、並べ替えに費用がかかる場合は、それをサポートするためにインデックスを追加/変更することを検討してください。

于 2013-03-03T17:27:56.723 に答える
40

ビューを強制的に並べ替えることに成功しました

SELECT TOP 9999999 ... ORDER BY something

残念ながら、ここSELECT TOP 100 PERCENTの問題により使用できません。

于 2013-12-16T06:26:00.767 に答える
-1

以下のロジックを試してください。

SELECT TOP(SELECT COUNT(SNO) From MyTable) * FROM bar ORDER BY SNO
于 2015-03-26T10:52:36.950 に答える
-1

エラーは次のとおりです。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

于 2013-12-11T07:10:35.447 に答える
-2

選択でTOP 100パーセントを使用するだけです:

     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
于 2014-11-21T14:37:33.853 に答える