我有三张桌子:
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
处于非可空状态,因此查询会为DocumentExt
和Tracking
中的每条记录返回一行。为了查询的目的,我需要它将Tracking.DocOtherId
视为可空,以便JOIN正常工作。有没有办法做到这一点?
编辑:我想我需要明确表示我需要在Tracking
中为 EACH 记录返回 ONE 记录,包括DocOtherId
中包含空字符串的那些。
例如:
TrackingId | DocumentName
---------------------------
1 SomeDoc2
2 NULL
3 SomeDoc1
... ...
编辑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中空字符串的记录。