【问题标题】:SQL Server conditional join of four tables in a View视图中四个表的 SQL Server 条件连接
【发布时间】: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

这最好用游标完成吗?

【问题讨论】:

    标签: sql-server windows join view left-join


    【解决方案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
    

    虽然您在以这种方式添加额外的joins 时需要注意重复项。在没有看到您的数据的情况下,这不是我们可以肯定地说的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-06
      • 2012-09-17
      • 1970-01-01
      • 2023-03-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多