2012-06-14 4 views
2

Ma structure de table est ci-dessous:Créer vue indexée

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 

Je veux créer vue indexée avec en dessous de la sortie:

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:

Ma table est très grand et je veux avoir au-dessus de la sortie. je peux obtenir ma requête, comme ci-dessous:

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 

ou

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 

ou

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 

Mais surtout requête est lent et je veux avoir une vue indexée d'avoir de meilleures performances. et en vue indexée je ne peux pas utiliser UNION ou UNPIVOT ou CROSS JOIN en vue indexée.

+3

[Qu'avez-vous essayé?] (Http://mattgemmell.com/2008/12/08/what-have-you-tried/) Aussi, bien que votre schéma soit bien présenté et clair, ce que vous demandez est: ne pas. Veuillez éditer la question afin que ce que vous demandez soit plus clair, et ce que vous avez essayé jusqu'à présent, et où vous rencontrez des problèmes. – GarethD

+0

@GarethD, s'il vous plaît voir mon edit. Merci. –

+0

Vous avez besoin d'UNPIVOT. Je ne me souviens pas si cela est autorisé dans les vues indexées. Et c'est en supposant que la ligne «2, 3, 5» dans les résultats souhaités est censé avoir la valeur de 1 et 5. –

Répondre

2

Et si vous avez créé une table Numbers pour faire essentiellement le travail de votre CROSS JOIN illégale?

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] 

Le WHERE AccID IS NOT NULL doit faire partie de la requête parce que les tables dérivées ne sont pas autorisés dans les vues indexées.

Questions connexes