MS SQL: alter indexed view by including additional columns from new table

假如想象 提交于 2020-01-23 08:59:39

问题


I need to update existing MS SQL indexed view by including additional columns values from newly created table. Indexed view:

CREATE OR ALTER VIEW [dbo].[MySelectionInfo]
  WITH schemabinding
  AS
    SELECT C.Id                                         id0,
           C.Code                                       Code1,
           C.Name                                       Name2,
           C.ProgramLevel                               Level3,
           C.Department                                 Department4,
           C.City                                       City10,
           C.STATE                                      State11,
           C.StartDate                                  StartDate12,
           C.Deadline                                   Deadline13,
           B.ID                                         Table_B_ID,
           A.Id                                        Table_A_ID

    FROM dbo.Table_A A
           INNER JOIN dbo.Table_B B ON A.id = B.Table_A_Id
           INNER JOIN dbo.Table_C C ON C.Table_B_Id = B.Id

New table:

CREATE TABLE [dbo].[Table_D] (
  [Id]               [int] IDENTITY (1, 1) PRIMARY KEY NOT NULL,
  [ModelName] [varchar](max)                    NOT NULL,
  [Table_C_Id]        [int]                             NOT NULL,
  [AttributeValue]   [varchar](max)                    NOT NULL,
  [CreatedDate]      [datetime]                        NOT NULL,
  [UpdatedDate]      [datetime]                        NOT NULL,
  CONSTRAINT FK_Table_C_Id FOREIGN KEY (Table_C_Id) REFERENCES some_schema.dbo.[Table_C] (Id)
    ON DELETE CASCADE
    ON UPDATE CASCADE
)

Data in the new table:

I want to include only some of the ModelName column values as a column names and AttributeValue as values in the select * from [dbo].[MySelectionInfo] result set:

I can achieve the desired result using the PIVOT function:

CREATE OR ALTER VIEW [dbo].[MySelectionInfo]
  WITH schemabinding
  AS
    SELECT C.Id                                         id0,
           C.Code                                       Code1,
           C.Name                                       Name2,
           C.StartDate                                  StartDate12,
           C.Deadline                                   Deadline13,
           B.ID                                         Table_B_ID,
           A.Id                                        Table_A_ID
    FROM dbo.Table_A A
           INNER JOIN dbo.Table_B B ON A.id = B.Table_A_Id
           INNER JOIN dbo.Table_C C ON C.Table_B_Id = B.Id
           LEFT JOIN (SELECT PivotTable.Table_C_Id,
                             PivotTable.attribute1,
                             PivotTable.attribute2,
                             PivotTable.attribute3
                      FROM (SELECT Table_D.Table_C_Id,
                                   Table_D.ModelName,
                                   Table_D.AttributeValue
                            FROM dbo.Table_C
                                   INNER JOIN dbo.Table_D
                                     ON Table_C.Id = Table_D.Table_C_Id) AS sourceTable
                               PIVOT (
                                 Max(AttributeValue) FOR ModelName IN (attribute1, attribute2, attribute3)
                               ) AS PivotTable) dbo.Table_D D ON D.Table_C_Id = C.Id

But, after running the SQL statement above, I am not be able to create the clustered index for the view, because LEFT JOIN, PIVOT, MAX are prohibited to be used in the indexed views.

Question: Is there any other solutions to achieve the desired result and still have an existing view as an Indexed view?


回答1:


if your data allow it, you could cross tab with case statements instead of PIVOTing:

/*
drop view dbo.mytestinfoview;
go
drop table dbo.Table1;
go
--*/

create table dbo.Table1
(
    id int,
    ModelName varchar(20),
    AttributeValue int
);


insert into dbo.Table1(id, ModelName, AttributeValue)
select distinct o.object_id, concat('attribute', v.id), o.attributevalue
from 
(
    select 
        object_id , 
        abs(checksum(newid())) % 2 as attributevalue
    from sys.objects
) as o
cross apply (values(1), (2), (3), (4)) as v(id)
go

create or alter view dbo.mytestinfoview
with schemabinding
as
    select id, count_big(*) as thecounter,
        sum(isnull(case ModelName when 'attribute1' then AttributeValue end, 0)) as attribute1,
        sum(isnull(case ModelName when 'attribute2' then AttributeValue else 0 end, 0)) as attribute2,
        sum(isnull(case ModelName when 'attribute3' then AttributeValue else 0 end, 0)) as attribute3
    from dbo.Table1
    group by id
go

create unique clustered index idx_v1 on dbo.mytestinfoview(id);
go

select * from dbo.mytestinfoview;
go


来源:https://stackoverflow.com/questions/59070076/ms-sql-alter-indexed-view-by-including-additional-columns-from-new-table

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!