[英]Creating View from Related Child Tables
我具有以下常规表结构(在我的作过的示例中原谅了以美国为中心的汽车制造商):
CREATE TABLE Car (
[Id] int PRIMARY KEY
)
CREATE TABLE Ford (
[FordId] int PRIMARY KEY, --also a foreign key on Car
[Model] nvarchar(max)
)
CREATE TABLE Chevy (
[ChevyId] int PRIMARY KEY, --also a foreign key on Car
[Model] nvarchar(max)
)
我想在这些表的顶部创建一个视图,以便可以检索所有Fords和Chevys,并在视图中仅包含一个生成的列来告诉我。 我的第一个刺是:
SELECT
c.CarId,
case when f.FordId is not null then 'Ford' else 'Chevy' end
FROM Car as c
LEFT JOIN Ford as f on c.Id = f.FordId
LEFT JOIN Chevy as ch on c.Id = ch.ChevyId
WHERE (f.FordId is not null or ch.ChevyId is not null)
但这会使我口中难闻,我担心表现。 我会更好地以单独的CTE值检索所有的福特和雪佛兰,然后对它们进行联合吗? 我完全走错了轨道吗? 我还将需要包括Model列(以及两个子表共有的其他一些列),这显然会使我的观点变成一系列case语句。 处理这种情况的“正确”方法是什么?
编辑 :以为我应该补充一点,该架构已经存在,因此无法更改基础表。
首先,让我们尝试看看两种方法各自的优缺点:
create view vw_Car1
as
SELECT
c.Id,
case when f.FordId is not null then 'Ford' else 'Chevy' end as Maker,
coalesce(f.Model, ch.Model) as Model
FROM Car as c
LEFT JOIN Ford as f on c.Id = f.FordId
LEFT JOIN Chevy as ch on c.Id = ch.ChevyId
WHERE (f.FordId is not null or ch.ChevyId is not null);
create view vw_Car2
as
select FordId as id, 'Ford' as Maker, Model from Ford
union all
select ChevyId as id, 'Chevy' as Maker, Model from Chevy;
当在联接中使用它时,第一个更好,特别是如果您不使用所有列。 例如,假设您在使用vw_Car
时有一个视图:
create table people (name nvarchar(128), Carid int);
insert into people
select 'John', 1 union all
select 'Paul', 2;
create view vw_people1
as
select
p.Name, c.Maker, c.Model
from people as p
left outer join vw_Car1 as c on c.ID = p.CarID;
create view vw_people2
as
select
p.Name, c.Maker, c.Model
from people as p
left outer join vw_Car2 as c on c.ID = p.CarID;
现在,如果要简单选择:
select Name from vw_people1;
select Name from vw_people2;
第一个方法是简单地从people
进行选择( vw_Car1
不会查询vw_Car1
)。 第二个将更复杂- Ford
和Chevy
将被同时查询。 您可能认为第一种方法更好,但让我们尝试另一个查询:
select *
from vw_people1
where Maker = 'Ford' and Model = 'Fiesta';
select *
from vw_people2
where Maker = 'Ford' and Model = 'Fiesta';
这里第二个会更快,特别是如果您在“ Model
列上有索引。
=> sql fiddle演示 -请参阅这些查询的查询计划。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.