我知道问题出在我的WHERE子句中,但我没有一个很好的解决方案来纠正这个问题。
如果第2部分中的条目未标记为已删除且链接到标记为已删除的第3条条目,则我将完全丢失该条目。
任何帮助都将不胜感激。
p.s同样的事情也发生在3到4之间 不幸的是,在我的时间之前,桌面结构无法改变。
Table FK PK bit
------------------------------------------
Section1 | JobID | Sect1ID | isDeleted
Section2 | Sect1ID | Sect2ID | isDeleted
Section3 | Sect2ID | Sect3ID | isDeleted
Section4 | Sect3ID | Sect4ID | isDeleted
@JobId int
AS
SET NOCOUNT ON
SELECT J.Section1,
J.Section2,
J.Section3,
J.Section4,
S1.Id AS Section1Id,
S1.[Order] + 1 AS S1Order,
S1.Text AS S1Text,
S2.Id AS Section2Id,
S2.Text AS S2Text,
S2.[Order] AS S2Order,
S3.Id AS Section3Id,
S3.Text AS S3Text,
S3.[Order] + 1 AS S3Order,
S4.Id AS Section4Id,
S4.Text AS S4Text,
S4.[Order] AS S4Order
FROM JT_Jobs J
JOIN JT_Section1 S1 ON J.JobId = S1.JobId
LEFT JOIN JT_Section2 S2 ON S1.Id = S2.Section1Id
LEFT JOIN JT_Section3 S3 ON S2.Id = S3.Section2Id
LEFT JOIN JT_Section4 S4 ON S3.Id = S4.Section3Id
WHERE J.JobId = @JobId
AND S1.IsDeleted = 0
AND (s2.IsDeleted is null or s2.IsDeleted = 0)
AND (s3.IsDeleted is null or s3.IsDeleted = 0)
AND (s4.IsDeleted is null or s4.IsDeleted = 0)
ORDER BY S1.[Order], S2.[Order], S3.[Order], S4.[Order]
答案 0 :(得分:3)
将连接条件放在join子句中而不是where子句
中 From JT_Jobs J
Join JT_Section1 S1
On S1.JobId = J.JobId
And S1.IsDeleted = 0
Left Join JT_Section2 S2
On S2.Section1Id=S1.Id
And (s2.IsDeleted is null or s2.IsDeleted = 0)
Left Join JT_Section3 S3
On S3.Section2Id = S2.iD
And (s3.IsDeleted is null or s3.IsDeleted = 0)
Left Join JT_Section4 S4
ON S4.Section3Id = S3.Id
And (s4.IsDeleted is null or s4.IsDeleted = 0)
Where J.JobId = @JobId
....解释,where子句中的谓词(布尔条件)仅在处理完所有连接后才被评估。
通过检查连接的两边,在所有连接条件为真的结果集中添加记录,然后 然后 ,处理(逻辑)连接,如果它是外连接,从外侧添加回来的 不 的记录在另一侧有匹配的记录。因此,连接条件仅应用于内侧,而外侧的记录则应用于内侧的记录。
因此,在处理完所有连接之后,在where子句中放置一个条件会导致它应用于最后一个中间结果集。此时所有这些外部记录都已添加回来,并且对于影响外部联接外侧的条件,它将消除在外部联接的后半部分中重新添加的所有记录,从而有效地将其转换为回到内部联接。
答案 1 :(得分:0)
将sN.IsDeleted = 0
添加到LEFT JOIN
子句中,而不是WHERE
子句中。
答案 2 :(得分:0)
如果在左连接右侧的表中引用where子句中的字段(除非ID为null),则将其转换为内连接。您必须将这些条件放入连接条件中。