希望通过 Left Outer Joint 添加到查询中的数据不重复

Want data added to the Query via Left Outer Joint to NOT repeat

我有一个数据库结构(下面的ER图),它有三级分层数据和第四级可选数据。

如果我编写一个查询来获取三个级别的非规范化数据 - 级别 1 到级别 3,三个表中的示例数据如下所示:

查询时,数据的这种布局非常简单,如下所示:

在 运行 下面的查询中,我得到以下输出(我尝试了各种组合,将 L1 集合组合到 L4 并将一个 L4 作为另一个查询移出,然后加入集合 L1 - L4 等)- 这又在预期的范围内。

SELECT        [Group].GroupId, [Group].GroupName, Category.CategoryId, Category.CategoryName, RLI.RLIId, RLI.RLIText, Comment.CommentId, Comment.CommentText, ManagementResponse.ManagementResponseId, 
                         ManagementResponse.ManagementResponseTest
FROM            Category INNER JOIN
                         [Group] ON Category.GroupId = [Group].GroupId INNER JOIN
                         RLI ON Category.CategoryId = RLI.CategoryId LEFT OUTER JOIN
                         ManagementResponse ON RLI.RLIId = ManagementResponse.RLIId LEFT OUTER JOIN
                         Comment ON RLI.RLIId = Comment.RLIId

但是,我需要以下格式的数据 - 这是我无法弄清楚如何获取的(我不希望在添加额外级别时重复 4 级数据4 个数据通过左外连接 ):

您需要指定 Comment.CommentId 等于 ManagementResponse.ManagementResponseId 或者为空。这可以是 JOIN 的一部分或单独的 WHERE

SELECT          [Group].GroupId, [Group].GroupName, Category.CategoryId, Category.CategoryName, RLI.RLIId, RLI.RLIText, Comment.CommentId, Comment.CommentText, ManagementResponse.ManagementResponseId, 
                         ManagementResponse.ManagementResponseTest
FROM            [Category]
INNER JOIN      [Group] ON Category.GroupId = [Group].GroupId 
INNER JOIN      [RLI] ON Category.CategoryId = RLI.CategoryId 
LEFT OUTER JOIN [ManagementResponse] ON RLI.RLIId = ManagementResponse.RLIId 
LEFT OUTER JOIN [Comment] ON RLI.RLIId = Comment.RLIId
WHERE           ManagementResponse.ManagementResponseId = Comment.CommentId OR ManagementResponse.ManagementResponseId IS NULL OR Comment.CommentId IS NULL

这假定这些 ID 开始相等是您要建模的关系。示例数据似乎表明了这一点,但这可能是您如何组装示例的巧合。或者,如果除了 RLIId 之外,CommentManagementResponse 之间没有任何关系,例如

WITH CommentAndResponse AS (
    SELECT Comment.CommentId, Comment.CommentText, ManagementResponse.ManagementResponseId, ManagementResponse.ManagementResponseTest,
        COALESCE(Comment.RLIId, ManagementResponse.RLIId) AS RLIId,
        ROW_NUMBER() OVER (ORDER BY Comment.CommentId, ManagementResponse.ManagementResponseId, PARTITION BY Comment.RLIId, ManagementResponse.RLIId) AS rn
    FROM Comment
    FULL JOIN ManagementResponse ON Comment.RLIId = ManagementResponse.RLIId)
SELECT          [Group].GroupId, [Group].GroupName, Category.CategoryId, Category.CategoryName, RLI.RLIId, RLI.RLIText, CommentAndResponse.CommentId, CommentAndResponse.CommentText, CommentAndResponse.ManagementResponseId, CommentAndResponse.ManagementResponseTest
FROM            [Category]
INNER JOIN      [Group] ON Category.GroupId = [Group].GroupId 
INNER JOIN      [RLI] ON Category.CategoryId = RLI.CategoryId 
LEFT OUTER JOIN [CommentAndResponse] ON RLI.RLIId = CommentAndResponse.RLIId AND CommentAndResponse.rn = 1

此查询将为您提供最终输出:

WITH CommentAndResponse AS (

SELECT Comment.CommentId,
         Comment.CommentText, 
         ManagementResponse.ManagementResponseId, 
         ManagementResponse.ManagementResponseTest,
    COALESCE(Comment.RLIId, ManagementResponse.RLIId) AS RLIId
 FROM (
    (SELECT Comment.CommentId, 
            Comment.CommentText,
            Comment.RLIId,
            ROW_NUMBER() OVER (PARTITION BY Comment.RLIId ORDER BY Comment.CommentId) AS CommentRowNumber
    FROM Comment) AS Comment
    FULL JOIN
    (SELECT  ManagementResponse.ManagementResponseId, 
            ManagementResponse.ManagementResponseTest,
            ManagementResponse.RLIId,
            ROW_NUMBER() OVER (PARTITION BY ManagementResponse.RLIId ORDER BY ManagementResponse.ManagementResponseId) AS ManagementResponseRowNumber   
    FROM ManagementResponse) AS ManagementResponse
    ON Comment.CommentRowNumber = ManagementResponse.ManagementResponseRowNumber AND Comment.RLIId = ManagementResponse.RLIId ) 
    )

SELECT          [Group].GroupId, [Group].GroupName, Category.CategoryId, Category.CategoryName, RLI.RLIId, RLI.RLIText, CommentAndResponse.CommentId, CommentAndResponse.CommentText, CommentAndResponse.ManagementResponseId, CommentAndResponse.ManagementResponseTest
FROM            [Category]
INNER JOIN      [Group] ON Category.GroupId = [Group].GroupId 
INNER JOIN      [RLI] ON Category.CategoryId = RLI.CategoryId 
LEFT OUTER JOIN [CommentAndResponse] ON RLI.RLIId = CommentAndResponse.RLIId