您可能知道,您无法使用自联接索引视图。实际上甚至是同一个表的两个连接,即使它在技术上不是自我连接。来自微软的几个人想出了一个解决方案。但它太复杂了我不明白!!!
问题的解决方案是:http://jmkehayias.blogspot.com/2008/12/creating-indexed-view-with-self-join.html
我想要应用此工作的视图是:
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
任何帮助都会有很大帮助!!!
提前非常感谢!
编辑:所以我发现这也行。请注意,我在第一个索引视图中连接到表一次,第二次在第二个非索引视图中连接到表。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
和
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
和
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
然后我可以根据自己的意愿在第一个视图上创建附加索引。我不确定这个解决方案(或者那个问题的解决方法)是否会真正加快性能,但我会告诉你。
答案 0 :(得分:1)
以下是我从博客中获得的内容
假设你想在dbo.circt_cstdn加入2次,即你想要像
这样的东西 owner tech
rowA a.nm b.nm
...
不是将值分为2列,而是将其分为2行(上面每行2行),并添加一列以说明哪一行适用于哪一列。请注意,行1.1和行1.2具有相同的数据(名称和列除外)
name for
row1.1 nm owner
row1.2 nm tech
...
然后你转动所有者和技术的最大名称列。注意 - max函数只是为了欺骗PIVOT(需要一些聚合函数),如果只有一个记录,你可以使用任何返回相同值的聚合函数 老板科技 row1 nm nm ...
现在,如果我们为您的查询执行此操作
创建一个表d,就像这个
i
1
2
使用此
交叉加入查询的第一部分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
现在让我们使用行为所有者,如果D.i是1,那么技术如果D.i是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
现在添加nm列。要获得名称,如果它是所有者行(d.i = 1),则加入circt_cstdn,如果是技术行(d.i = 2),则加入dvc。注意 - 我在此处尝试了一个快捷方式,将其置于连接条件中。如果它不起作用,请尝试使用博客文章方式(在circt.circt_cstdn_user_id OR dvc.circt_cstdn_user_id上进行连接,然后使用WHERE子句进行过滤)
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
使用该视图创建视图并创建索引
create VIEW vw_lookup_test_imed
WITH SCHEMABINDING
AS
<<query above>>
GO
spell to create INDEX
现在您可以将PersonType列转换为所有者和技术列
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
如果存在语法错误(由于我现在无法访问数据库,因此必然会有很多错误)请告诉我。
答案 1 :(得分:0)
我认为这种JOIN语法很糟糕,并且源自MS Access。啊。 我建议你使用:
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
这种语法更清晰,更易于理解,并且在SQL Server,Firebird,Oracle,MySQL和其他许多方面都得到了认可。 现在你可以更好地看到“表格”之间的关系。 当您加入相同的“表”两次或更多次时,您需要为每个“表”添加别名。在一行“circt_cstdn”别名为“o”。另一方面,“circt_cstdn”别名为“t”。
我建议使用LEFT JOIN或INNER JOIN代替JOIN。