首页 > 解决方案 > 下级表可能没有所有预期值的问题构建视图

问题描述

我的问题是我正在尝试构建 3 个表的视图,表 1 和表 2 保证系统中每个文档的每个表都有一个条目/行,表 3 最多有 5 个条目/行,但可能更少。

我当前的 SQL 代码仅在所有预期的条目/行都存在时才有效,如果文档在 teble3 中只有四个条目,则视图中不会创建行。

我希望表中有一行在没有找到记录的情况下为 NULL。

SELECT M.DocumentID, 
    M.ProjectID, 
    DOC.CurrentStatusID, 
    Vv0.ValueText AS vDocNumber,
    Vv1.ValueText AS vTitle1,
    Vv2.ValueText AS vTitle2,
    Vv3.ValueText AS vTitle3,
    Vv4.ValueText AS vProjectNumber,
Vv5.ValueText AS vRevision
        
FROM [JDS01].[dbo].[DocumentsInProjects] M
INNER JOIN [JDS01].[dbo].[Documents] AS DOC ON M.DocumentID = DOC.DocumentID
LEFT JOIN [JDS01].[dbo].VariableValue AS Vv0 ON M.DocumentID = Vv0.DocumentID
LEFT JOIN [JDS01].[dbo].VariableValue AS Vv1 ON M.DocumentID = Vv1.DocumentID
LEFT JOIN [JDS01].[dbo].VariableValue AS Vv2 ON M.DocumentID = Vv2.DocumentID
LEFT JOIN [JDS01].[dbo].VariableValue AS Vv3 ON M.DocumentID = Vv3.DocumentID
LEFT JOIN [JDS01].[dbo].VariableValue AS Vv4 ON M.DocumentID = Vv4.DocumentID
LEFT JOIN [JDS01].[dbo].VariableValue AS Vv5 ON M.DocumentID = Vv5.DocumentID 

WHERE M.Deleted = 0

AND Vv0.VariableID = 1061
AND Vv0.ConfigurationID = 2
AND Vv0.RevisionNo = (SELECT MAX(xx.RevisionNo) FROM [JDS01].[dbo].[VariableValue] AS xx
                    WHERE Vv0.DocumentID = xx.DocumentID
                    AND xx.ConfigurationID = 2
                    AND xx.VariableID = 1061)

AND Vv1.VariableID = 50
AND Vv1.ConfigurationID = 2
AND Vv1.RevisionNo = (SELECT MAX(xx.RevisionNo) FROM [JDS01].[dbo].[VariableValue] AS xx
                    WHERE Vv1.DocumentID = xx.DocumentID
                    AND xx.ConfigurationID = 2
                    AND xx.VariableID = 50)
AND Vv2.VariableID = 51
AND Vv2.ConfigurationID = 2
AND Vv2.RevisionNo = (SELECT MAX(xx.RevisionNo) FROM [JDS01].[dbo].[VariableValue] AS xx
                    WHERE Vv2.DocumentID = xx.DocumentID
                    AND xx.ConfigurationID = 2
                    AND xx.VariableID = 51)
AND Vv3.VariableID = 52
AND Vv3.ConfigurationID = 2
AND Vv3.RevisionNo = (SELECT MAX(xx.RevisionNo) FROM [JDS01].[dbo].[VariableValue] AS xx
                    WHERE Vv3.DocumentID = xx.DocumentID
                    AND xx.ConfigurationID = 2
                    AND xx.VariableID = 52)
AND Vv4.VariableID = 48
AND Vv4.ConfigurationID = 2
AND Vv4.RevisionNo = (SELECT MAX(xx.RevisionNo) FROM [JDS01].[dbo].[VariableValue] AS xx
                    WHERE Vv4.DocumentID = xx.DocumentID
                    AND xx.ConfigurationID = 2
                    AND xx.VariableID = 48)

  AND Vv5.VariableID = 1054
  AND Vv5.ConfigurationID = 2
  AND Vv5.RevisionNo = (SELECT MAX(xx.RevisionNo) FROM [JDS01].[dbo].[VariableValue] AS xx
                    WHERE Vv5.DocumentID = xx.DocumentID
                    AND xx.ConfigurationID = 2
                    AND xx.VariableID = 1054)

标签: sqlsql-server

解决方案


要扩展 Gordon 的答案(我认为这是正确的),请将 AND 条件从 WHERE 子句中移出,使其成为每个 LEFT JOIN 的关联 ON 条件的一部分,例如:

LEFT JOIN [JDS01].[dbo].VariableValue AS Vv0 ON M.DocumentID = Vv0.DocumentID
      AND Vv0.VariableID = 1061
      AND Vv0.ConfigurationID = 2
      AND Vv0.RevisionNo = (SELECT MAX(xx.RevisionNo) FROM [JDS01].[dbo].[VariableValue] AS xx
                WHERE Vv0.DocumentID = xx.DocumentID
                AND xx.ConfigurationID = 2
                AND xx.VariableID = 1061)

如果没有关联的条目,将条件放在 WHERE 子句中将从结果集中完全删除该行,而将条件放在 LEFT JOIN 的 ON 子句中将允许返回带有 NULL 值的行。


推荐阅读