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_BIGand SUM,因为它们分布在集合的加减法上,SUM(a UNION ALL b) = SUM(a) + SUM(b)SUM(a EXCEPT ALL b) = SUM(a) - SUM(b).

该属性是索引可维护所必需的。

当从基础表中插入、更新或删除新记录时,不需要重新评估整个视图:新记录的值只是从聚合值中添加或减去。

此外, aCOUNT_BIG也应该是视图的一部分,以跟踪记录的删除(当它变为 时0,应该从视图索引中删除一条记录)。

于 2010-11-03T17:11:29.393 回答
-2

如果您使用 1=1 的内部连接,它将满足条件,并允许连接。

Select * From x inner join y on 1=1

于 2019-03-06T06:07:01.590 回答