4

別のスレッドで、ストアドプロシージャをビューに変換する方法の実例を取得しました。これは、顧客名を注文マッピングに保持します。注文は、注文がない場合のNULLを含む、注文のコンマ区切りリストです。したがって、以下の表の場合、ビューに表示するには次のものが必要です。

Name     Orders
'John'   New Hat, New Book, New Phone
'Marry'  NULL

ビューにインデックスを付ける必要がありますが、ビュー内のSELECTクエリにAPPLYやサブクエリがある場合はインデックスを付けることができません。このビューをインデックス付きビューに変換することは可能ですか?

create table Customers (CustomerId int, CustomerName VARCHAR(100))
create table Orders    (CustomerId int, OrderName VARCHAR(100))

insert into Customers  (CustomerId, CustomerName) select 1, 'John' union all select 2, 'Marry'
insert into Orders     (CustomerId, OrderName)    select 1, 'New Hat' union all select 1, 'New Book' union all select 1, 'New Phone'
go

create view OrderView as 
select c.CustomerName, x.OrderNames        
from Customers c            
cross apply (select stuff((select ',' + OrderName from Orders o 
      where o.CustomerId = c.CustomerId for xml path('')),1,1,'') 
      as OrderNames) x
go
4

2 に答える 2

12

このビューにインデックスを付けることはできません。

基本的に、ここでは集計関数を使用しています(に偽装CROSS APPLY)。

インデックス付きビューで許可される唯一の集計関数はとです。これは、セットの加算COUNT_BIGSUM減算、つまり、に分散されるためSUM(a UNION ALL b) = SUM(a) + SUM(b)ですSUM(a EXCEPT ALL b) = SUM(a) - SUM(b)

このプロパティは、インデックスを保守可能にするために必要です。

基になるテーブルから新しいレコードが挿入、更新、または削除された場合、ビュー全体を再評価する必要はありません。新しいレコードの値は、集計値に加算または減算されるだけです。

さらに、COUNT_BIGレコードの削除を追跡するために、aもビューの一部である必要があります(レコードがになると0、ビューインデックスからレコードを削除する必要があります)。

于 2010-11-03T17:11:29.393 に答える
-2

1 = 1の内部結合を使用すると、条件が満たされ、結合が許可されます。

選択*1=1のx内部結合yから

于 2019-03-06T06:07:01.590 に答える