视图中四个表的 SQL Server 条件连接
Posted
技术标签:
【中文标题】视图中四个表的 SQL Server 条件连接【英文标题】:SQL Server conditional join of four tables in a View 【发布时间】:2016-12-01 13:19:37 【问题描述】:这个让我发疯,甚至不可能。我在下面列出了四个表。为简洁起见,我删除了不重要的列、索引、键、外键等。
CREATE TABLE Client(
ClientID uniqueidentifier ROWGUIDCOL NOT NULL DEFAULT (newid()),
ClientName varchar(250) not null
);
GO
CREATE TABLE Instance(
InstanceID uniqueidentifier ROWGUIDCOL NOT NULL DEFAULT (newid()),
ClientID uniqueidentifier not null, /* FK into Client */
InstanceName varchar(48) not null
);
GO
CREATE TABLE Object(
ObjectID uniqueidentifier ROWGUIDCOL NOT NULL DEFAULT (newid()),
ClientID uniqueidentifier not null, /* FK into Client */
InstanceID uniqueidentifier null, /* FK into Instance */
Path varchar(260) not null
);
GO
CREATE TABLE History(
Timestamp datetime DEFAULT (getdate()),
ClientID uniqueidentifier null, /* if not null, references Client */
InstanceID uniqueidentifier null, /* if not null, references Instance */
ObjectID uniqueidentifier null, /* if not null, references Object */
Details varchar(1024)
);
GO
我正在尝试在历史记录表上创建一个视图。视图中棘手的列是 ClientName。如果 History.ClientID 不为空,那么这很容易。但是如果 History.ClientID is null 而 ObjectID is not null,则需要通过 History.ObjectID->Object.ClientID->Client.ClientName 获取 ClientName。
这是我能想到的最好的方法,如果 History.ClientID 不为 null,则该方法有效,但如果 History.ClientID 为 null,我不知道如何通过 ObjectID 获取 ClientName。我希望这一切都清楚了。
CREATE VIEW History_Report as
SELECT
H.TimeStamp,
C.ClientName,
Q.InstanceName,
O.Path,
H.Details
from
History H
left join Instance Q ON (H.InstanceID = Q.InstanceID)
left join Object O on (H.ObjectID = O.ObjectID)
left join Client C on (H.ClientID = C.ClientID)
GO
这最好用游标完成吗?
【问题讨论】:
【参考方案1】:我认为你的意思是这样的:
CREATE VIEW History_Report as
SELECT
H.TimeStamp,
COALESCE(C.ClientName, CO.ClientName) ClientName,
Q.InstanceName,
O.Path,
H.Details
from
History H
left join Instance Q ON (H.InstanceID = Q.InstanceID)
left join Object O on (H.ObjectID = O.ObjectID)
left join Client C on (H.ClientID = C.ClientID)
LEFT JOIN Client CO ON (O.ClientID = CO.ClientID)
GO
【讨论】:
太棒了!谢谢。我忘记了 COALESCE。【参考方案2】:简单的方法是在查询中添加一个额外的join
:
CREATE VIEW History_Report as
SELECT
H.TimeStamp,
isnull(C.ClientName, CO.ClientName) as ClientName,
Q.InstanceName,
O.Path,
H.Details
from History H
left join Instance Q
on(H.InstanceID = Q.InstanceID)
left join Object O
on(H.ObjectID = O.ObjectID)
left join Client C
on(H.ClientID = C.ClientID)
left join Client CO
on(O.ClientID = CO.ClientID
and H.ClientID is null -- This will help limit duplicates
)
GO
虽然您在以这种方式添加额外的join
s 时需要注意重复项。在没有看到您的数据的情况下,这不是我们可以肯定地说的。
【讨论】:
以上是关于视图中四个表的 SQL Server 条件连接的主要内容,如果未能解决你的问题,请参考以下文章
SQL Server 是不是在复杂视图中传播 WHERE 条件?