使用LEFT和INNER JOIN创建视图

时间:2014-10-08 09:48:34

标签: sql left-join inner-join

我有一个关于在这里创建视图的问题。我想出了一个简单的例子来说明这个问题。

  • 合同有标题和行项目。
  • 合约标题以及行项目具有不同表格的不同状态,并且需要ARE(非空)
  • 合同标题不需要
  • ContactID

见下表:

[Contacts]
PK.ContactID
ContactName

[ContractHeader]
PK.ContractID
ContractThruDate
FK.ContactID
FK.ContractStatusID (REQUIRED)

[ContractStatus]
PK.ContractStatusID
ContractStatusName

[ContractLineItem]
PK.ContractLineItemID
ContractLineItemDate
ContractLineItemName
FK.ContractLineItemStatusID (REQUIRED)
FK.ContractID

[ContractLineItemStatus]
PK.ContractLineItemStatusID
ContractLineItemStatusName

现在,如果我想创建一个完整的视图,我会这样做:

SELECT *
FROM ContractHeader CH
   INNER JOIN ContractStatus CS ON CH.ContractStatusID = CS.ContractStatusID
   LEFT JOIN Contacts CON ON CH.ContactID = CON.ContactID
   LEFT JOIN ContractLineItem CLI ON CLI.ContractID = CH.ContractID
   ...

到目前为止,我有Contacts,ContractHeader,ContractStatuses和ContractLineItems,所以我可以轻松添加

   ...
   LEFT JOIN ContractLineItemStatus CLIS ON CLI.ContractLineItemStatusID = CLIS.ContractLineStatusID

但是,由于在加入ContractLineItem时需要ContractLineItemStatus,我希望在ContractLineItem的LEFT JOIN内INNER JOIN ContractLineStatus。

这可能吗?或者,一旦父视图在视图中被LEFT JOIN-ed,我是否必须继续对所有内容进行LEFT JOIN?

2 个答案:

答案 0 :(得分:1)

我认为此链接可以回答您的问题:http://weblogs.sqlteam.com/jeffs/archive/2007/10/11/mixing-inner-outer-joins-sql.aspx

总结:

  • 左连接后跟左连接......
  • ...这可能会导致信息“丢失”,在这种情况下,您可能需要使用子查询来处理它。

对于您的示例案例:

SELECT *
FROM ContractHeader CH
    INNER JOIN ContractStatus CS ON CH.ContractStatusID = CS.ContractStatusID
    LEFT JOIN Contacts CON ON CH.ContactID = CON.ContactID
    LEFT JOIN (
        SELECT * FROM ContractLineItem CLI
        INNER JOIN ContractLineItemStatus CLIS ON CLI.ContractLineItemStatusID = CLIS.ContractLineStatusID
    ) AS CLI_AND_S ON CH.ContractID = CLI_AND_S.ContractID

所以回答你的问题:不,如果你在左连接后使用内连接,你将失去没有ContractLineItem的ContractHeader。 Yo可以使用子查询保留ContractLineItem和ContractLineItemStatus之间的内部联接。

编辑:替换了之前不应该有效的查询

答案 1 :(得分:0)

如果在ContractLineItem和ContractLineItemStatus表之间放置INNER JOIN,如果没有关于一个ContractStatus的ContractLineItem,您将删除那些ContractStatus行。因此,如果您的初始目标是查看所有ContractStatus,无论是否有其他信息,您都无法在这两个表之间应用INNER JOIN