2012-06-14 6 views
2

Моя структура таблицы ниже:Создание индексированного представления

MyTable (ID Int, AccID1 Int, AccID2 Int, AccID3 int) 

ID  AccID1  AccID2  AccID3 
---- -------- -------- -------- 
    1  12   2   NULL 
    2  4   12   1 
    3  NULL  NULL   5 
    4  7   NULL   1 

Я хочу создать индексный вид с ниже выхода:

ID Level  Value 
---- ----- ------- 
1  1   12 
1  2   2 
2  1   4 
2  2   12 
2  3   1 
3  3   5 
4  1   7 
4  3   1 

EDIT:

Мой стол очень огромный, и я хочу иметь выше выход. я могу получить мой запрос, например, как показано ниже:

Select ID, 
     Case StrLevel 
      When 'AccID1' Then 1 
      When 'AccID2' Then 2 
      Else 3 
     End AS [Level], 
     AccID as Value 
From (
     Select A.ID, A.AccID1, A.AccID2, A.AccID3 
     From MyTable A 
     )as p 
UNPIVOT (AccID FOR [StrLevel] IN (AccID1, AccID2, AccID3)) AS unpvt 

или

Select * 
from (
     select MyTable.ID, 
       num.n as [Level], 
       Case Num.n 
        When 1 Then MyTable.AccID1 
        When 2 Then MyTable.AccID2 
        Else MyTable.AccID3 
       End AS AccID 
     from myTable 
     cross join (select 1 
        union select 2 
        union select 3)Num(n) 
    )Z 
Where Z.AccID IS NOT NULL 

или

Select A.ID, 
      2 AS [Level], 
      A.AccID1 AS AccID 
    From MyTable A 
    Where A.AccID1 IS NOT NULL 

    Union 

    Select A.ID, 
      2 AS [Level], 
      A.AccID2 
    From MyTable A 
    Where A.AccID2 IS NOT NULL 

    Union 

    Select A.ID, 
      3 AS [Level], 
      A.AccID3 
    From MyTable A 
    Where A.AccID3 IS NOT NULL 

Но выше запрос является медленным, и я хочу, чтобы индексировали представление, чтобы иметь более высокую производительность. и в индексированном виде я не могу использовать UNION или UNPIVOT или CROSS JOIN в индексированном виде.

+3

[Что вы пытались?] (Http://mattgemmell.com/2008/12/08/what-have-you-tried/) Также, когда ваша схема хорошо представлена ​​и понятна, то, что вы на самом деле спрашиваете, не. Пожалуйста, отредактируйте вопрос так, чтобы то, что вы просите, более ясное и то, что вы пробовали до сих пор, и где вы сталкиваетесь с проблемами. – GarethD

+0

@GarethD, см. Мое редактирование. Благодарю. –

+0

Вам нужен 'UNPIVOT'. Не могу вспомнить, разрешено ли это в индексированных представлениях. И это предполагает, что строка '2, 3, 5' в желаемых результатах должна иметь значение 1 не 5. –

ответ

2

Что делать, если вы создали таблицу Numbers, чтобы существенно выполнить работу вашего незаконного CROSS JOIN?

Create Table Numbers (number INT NOT NULL PRIMARY KEY) 
Go 

Insert Numbers 
Select top 30000 row_number() over (order by (select 1)) as rn 
from sys.all_objects s1 cross join sys.all_objects s2 
go 

Create view v_unpivot with schemabinding 
as 
Select MyTable.ID, 
     n.number as [Level], 
     Case n.number 
      When 1 Then MyTable.AccID1 
      When 2 Then MyTable.AccID2 
      Else MyTable.AccID3 
     End AS AccID 
From dbo.Mytable 
Join dbo.Numbers n on n.number BETWEEN 1 AND 3 
go 

Create unique clustered index pk_v_unpivot on v_unpivot (ID, [Level]) 
go 

Select 
    ID, 
    [Level], 
    AccID 
From v_unpivot with (noexpand) 
Where AccID IS NOT NULL 
Order by ID, [Level] 

WHERE AccID IS NOT NULL должен быть частью запроса, так как производные таблицы, не допускаются в индексированных представлениях.

Смежные вопросы