断开的表上的INNER JOIN(非可空字段)

时间:2014-04-22 16:16:57

标签: sql sql-server tsql inner-join

我有三张桌子:

Document                     DocumentExt           Tracking
-------------------------    -----------------     --------------------------------------------
ID  |  Name   |   DocType    DocId  |  OtherId     ID  |  DocOtherId  |  DocType  |  AccessTime
-------------------------    -----------------     --------------------------------------------   
1      SomeDoc    Z          1         Doc1        1      Doc2           X          [Date here]
2      SomeDoc2   X          2         Doc2        2                     A          [Date here]
3      SomeDoc3   Y          3         Doc3        3      Doc1           Z          [Date here]
...    ...        ...        ...       ...         ...    ...            ...        ...

请注意Tracking.DocOtherId中的缺失值。这是一个不可为空的字段,默认为空字符串。

问题是我需要在这两个上执行连接,包括 Tracking 中每条记录的一行,还包括来自Document的相关信息。如:

SELECT 
    Tracking.ID, Document.Name 
FROM 
    Tracking
INNER JOIN 
    DocumentExt ON DocumentExt.OtherId = Tracking.DocOtherId
INNER JOIN 
    Document ON Document.ID = DocumentExt.DocId

但是,由于Tracking.DocOtherId处于非可空状态,因此查询会为DocumentExtTracking中的每条记录返回一行。为了查询的目的,我需要它将Tracking.DocOtherId视为可空,以便JOIN正常工作。有没有办法做到这一点?

编辑:我想我需要明确表示我需要在Tracking中为 EACH 记录返回 ONE 记录,包括DocOtherId中包含空字符串的那些。

例如:

TrackingId  |  DocumentName
---------------------------
1              SomeDoc2
2              NULL
3              SomeDoc1
...            ...

编辑2 :已标记为已关闭。我认为这一切都错了,我采取了完全不同的方法。

2 个答案:

答案 0 :(得分:0)

如果您的数据不是很大,您可以尝试使用临时表来剥离数据,然后对精炼数据进行连接。例如:

编辑:回复下面的第一条评论

这第一部分将为您提供所需的临时表,而不需要空字符串,而是空字符串将为空

Select ID, 
     case when DocOtherId = '' then null else DocOtherId end,
     AccessTime
     into #tracking
From Tracking

然后使用此临时表以与原始方式相同的方式连接回数据。在这个例子中,您只需将#tracking用于跟踪,但您可以根据需要调用临时表。

SELECT 
    Tracking.ID, Document.Name 
FROM 
    #tracking
INNER JOIN 
    DocumentExt ON DocumentExt.OtherId = Tracking.DocOtherId
INNER JOIN 
    Document ON Document.ID = DocumentExt.DocId

答案 1 :(得分:0)

我看到了这个评论:

  

我需要跟踪的所有记录。

这意味着您需要 OUTER 加入,而不是INNER加入。使用coalesce()函数显示缺少名称的通用值。

 SELECT Tracking.ID, coalesce(Document.Name,'') As Name
 FROM Tracking t
 LEFT JOIN DocumentExt de ON de.OtherID = t.DocOtherId
 LEFT JOIN Document d on d.ID = de.DocID

这将在跟踪表中返回 EACH 记录的 ONE 记录,包括DocOtherId中空字符串的记录。