Vous avez besoin d'une aide sérieuse à l'auto problème se joindre
Question
Eh bien comme vous le savez, vous ne pouvez pas indexer une vue avec une jointure réflexive. Et bien en fait même deux jointures de la même table, même si ce n'est pas techniquement une jointure réflexive. Un couple de gars de Microsoft est venu avec un travail autour. Mais il est tellement compliqué que je ne le comprends pas !!!
La solution au problème est ici: http://jmkehayias.blogspot.com/2008/12/creating-indexed-view-with-self-join.html
Le point de vue que je veux appliquer ce travail autour de est:
create VIEW vw_lookup_test
WITH SCHEMABINDING
AS
select
count_big(*) as [count_all],
awc_txt,
city_nm,
str_nm,
stru_no,
o.circt_cstdn_nm [owner],
t.circt_cstdn_nm [tech],
dvc.circt_nm,
data_orgtn_yr
from
((dbo.dvc
join dbo.circt
on dvc.circt_nm = circt.circt_nm)
join dbo.circt_cstdn o
on circt.circt_cstdn_user_id = o.circt_cstdn_user_id)
join dbo.circt_cstdn t
on dvc.circt_cstdn_user_id = t.circt_cstdn_user_id
group by
awc_txt,
city_nm,
str_nm,
stru_no,
o.circt_cstdn_nm,
t.circt_cstdn_nm,
dvc.circt_nm,
data_orgtn_yr
go
Toute aide serait grandement aprécié !!!
Merci beaucoup à l'avance!
EDIT: Je trouve que ce sera aussi le travail. Notez que je me joins à la table une fois dans la première vue indexée, et la deuxième fois en deuxième Teh vue non indexée.
alter VIEW vw_lookup_owner_test2
WITH SCHEMABINDING
AS
select
count_big(*) as [countAll],
awc_txt,
city_nm,
str_nm,
stru_no,
dvc.circt_nm,
circt_cstdn_nm,
data_orgtn_yr,
dvc.circt_cstdn_user_id
from dbo.dvc
join dbo.circt
on dvc.circt_nm = circt.circt_nm
join dbo.circt_cstdn o
on circt.circt_cstdn_user_id = o.circt_cstdn_user_id
group by
awc_txt,
city_nm,
str_nm,
stru_no,
dvc.circt_nm,
circt_cstdn_nm,
data_orgtn_yr,
dvc.circt_cstdn_user_id
go
et
CREATE UNIQUE CLUSTERED INDEX [idx_vw_lookup_owner2_test1] ON [dbo].[vw_lookup_owner_test2]
(
[awc_txt] ASC,
[city_nm] ASC,
[str_nm] ASC,
[stru_no] ASC,
[circt_nm] ASC,
[circt_cstdn_nm] ASC,
[data_orgtn_yr] ASC,
[circt_cstdn_user_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
et
create view vw_lookup_dvc_loc
as
select
awc_txt,
city_nm,
str_nm,
stru_no,
circt_nm,
o.circt_cstdn_nm as [owner],
--o.circt_cstdn_user_id,
t.circt_cstdn_nm as tech,
data_orgtn_yr
from vw_lookup_owner_test2 o With (NOEXPAND)
join circt_cstdn t
on o.circt_cstdn_user_id = t.circt_cstdn_user_id
group by
awc_txt,
city_nm,
str_nm,
stru_no,
circt_nm,
o.circt_cstdn_nm,
data_orgtn_yr,
t.circt_cstdn_nm
--o.circt_cstdn_user_id
Je peux alors créer additon index sur la première vue que je souhaite. Je ne sais pas si cette solution (ou la solution de contournement pour cette question) sera effectivement accélérer preformance, mais je vais vous laisser savoir.
La solution
Voici ce que je suis de la blogpost
-
Soit s dire que vous voulez joindre 2 fois sur dbo.circt_cstdn vous voulez dire quelque chose comme
owner tech rowA a.nm b.nm ...
-
Au lieu d'obtenir les valeurs dans 2 colonnes vous en 2 lignes (2 pour chaque ligne ci-dessus) et ajouter une colonne supplémentaire pour dire quelle ligne est pour quelle colonne. Notez que la ligne 1.1 et la ligne 1.2 ont les mêmes données (à l'exception du nom et des colonnes)
name for row1.1 nm owner row1.2 nm tech ...
-
Ensuite, vous pivoter sur max de la colonne de nom pour le propriétaire et technologie. Remarque - la fonction max est juste pour tromper le PIVOT (qui nécessite une certaine fonction d'agrégation), vous pouvez utiliser une fonction d'agrégation qui retourne la même valeur s'il n'y a qu'un seul enregistrement tech propriétaire row1 nm nm ...
Maintenant, si nous le faisons pour votre requête
-
Créer une table d, comme celui-ci
i 1 2
-
Cross se joindre à la première partie de votre requête avec cette
SELECT count_big(*) as [count_all], awc_txt, city_nm, str_nm, stru_no, dvc.circt_nm, data_orgtn_yr FROM dbo.dvc INNER JOIN dbo.circt on dvc.circt_nm = circt.circt_nm CROSS JOIN dbo.d GROUP BY awc_txt, city_nm, str_nm, stru_no, dvc.circt_nm, data_orgtn_yr, d.i
-
Maintenant, nous allons utiliser la ligne pour le propriétaire si D.i est 1, et la technologie si D.i est 2
SELECT count_big(*) as [count_all], awc_txt, city_nm, str_nm, stru_no, dvc.circt_nm, data_orgtn_yr, Case WHEN d.i = 1 THEN 'Owner' WHEN d.i = 2 THEN 'Tech' END FROM dbo.dvc INNER JOIN dbo.circt on dvc.circt_nm = circt.circt_nm CROSS JOIN dbo.d GROUP BY awc_txt, city_nm, str_nm, stru_no, dvc.circt_nm, data_orgtn_yr, Case WHEN d.i = 1 THEN 'Owner' WHEN d.i = 2 THEN 'Tech' END
-
Maintenant, ajoutez la colonne nm. Pour obtenir le nom que vous rejoignez circt_cstdn avec circt si elle est une ligne de propriétaire (d.i = 1), et avec DVC si elle est une ligne de technologie (d.i = 2). Remarque - J'ai essayé un raccourci ici en mettant cela dans la condition de jointure. Si cela ne fonctionne pas essayer la voie post blog (faire une jointure sur circt.circt_cstdn_user_id ou dvc.circt_cstdn_user_id, puis utilisez la clause WHERE pour filtrer)
SELECT count_big(*) as [count_all], awc_txt, city_nm, str_nm, stru_no, dvc.circt_nm, data_orgtn_yr, Case WHEN d.i = 1 THEN 'Owner' WHEN d.i = 2 THEN 'Tech' END as PersonType, circt_cstdn_nm FROM dbo.dvc INNER JOIN dbo.circt on dvc.circt_nm = circt.circt_nm CROSS JOIN dbo.d INNER JOIN dbo.circt_cstdn on circt_cstdn_user_id = CASE WHEN d.i = 1 THEN circt.circt_cstdn_user_id WHEN d.i = 2 THEN dvc.circt_cstdn_user_id END GROUP BY awc_txt, city_nm, str_nm, stru_no, dvc.circt_nm, data_orgtn_yr, Case WHEN d.i = 1 THEN 'Owner' WHEN d.i = 2 THEN 'Tech' END, circt_cstdn_nm
-
Créer une vue à l'aide et que créer l'index
create VIEW vw_lookup_test_imed WITH SCHEMABINDING AS <<query above>> GO spell to create INDEX
-
Maintenant, vous PIVOT pour convertir la colonne PersonType aux colonnes et le propriétaire Tech
SELECT count_all, awc_txt, city_nm, str_nm, stru_no, dvc.circt_nm, data_orgtn_yr, [Owner], [Tech] FROM ( SELECT count_all, awc_txt, city_nm, str_nm, stru_no, dvc.circt_nm, data_orgtn_yr, PersonType, circt_cstdn_nm FROM dbo.vw_lookup_test_imed WITH (NOEXPAND) ) src PIVOT ( MAX(circt_cstdn_nm) FOR PersonType IN ([Owner], [Tech]) ) pvt
S'il y a des erreurs de syntaxe (il y a forcément beaucoup parce que je n'ai pas accès à une base de données en ce moment) faites-moi savoir.
Autres conseils
Je pense que cette syntaxe JOIN est horrible et origine de MS Access. Pouah. Je vous recommande d'utiliser:
select
count_big(*) as [count_all],
awc_txt,
city_nm,
str_nm,
stru_no,
o.circt_cstdn_nm [owner],
t.circt_cstdn_nm [tech],
dvc.circt_nm,
data_orgtn_yr
-- HERE
from dbo.dvc
join dbo.circt on (dvc.circt_nm = circt.circt_nm)
join dbo.circt_cstdn o on (circt.circt_cstdn_user_id = o.circt_cstdn_user_id)
join dbo.circt_cstdn t on (dvc.circt_cstdn_user_id = t.circt_cstdn_user_id)
group by
awc_txt,
city_nm,
str_nm,
stru_no,
o.circt_cstdn_nm,
t.circt_cstdn_nm,
dvc.circt_nm,
data_orgtn_yr
Cette syntaxe est plus propre, plus compréhensible et est reconnu dans SQL Server, Firebird, Oracle, MySQL et d'autres beaucoup. Maintenant, vous pouvez voir mieux les relations entre les « tables ». Lorsque vous rejoignez la même « table » deux fois ou plus, vous devez alias chacun. Sur une ligne « circt_cstdn » est Lissé comme « o ». Sur une autre ligne, "circt_cstdn" est Lissé comme "t".
Je recommande l'utilisation de LEFT JOIN ou INNER JOIN à la place JOIN.