2017-04-21 74 views
0

在SQL Server中,我有以下情况:过滤递归SQL查询相交的可能,并choosen项目

  1. 选项和相关群体:

    Groups(Id, Description) 
    Options(Id, GroupId, Description) 
    
  2. 节点配置了选项:

    Nodes(Id, ParentNodeId, Description) 
    Configurations(Id, NodeId, OptionId) 
    

因此,一个节点可以有一个或多个选项,但一个每组

  • 用户选择:

    Choices (Guid, OptionId) 
    
  • 在输出I想有节点,以递归方式,配置选择选项。 例如:

    Groups 
    1, "Eyes Color" 
    2, "Hair Color" 
    Options 
    1, 1, "Blue" 
    2, 1, "Brown" 
    3, 2, "Blonde" 
    4, 2, "Black" 
    Nodes 
    1, NULL, "Elizabeth" 
    2, NULL, "John" 
    Configurations 
    1, 1, 1 --(Elizabeth, Blue) 
    1, 1, 3 --(Elizabeth, Blonde) 
    2, 1, 4 --(John, Black) 
    

    可能的选择:

    Eyes Color: NULL -- it means there isn't record in choices table for this option 
    Hair Color: NULL 
    Result: Elizabeth, John 
    Eyes Color: "Blue" 
    Hair Color: NULL 
    Result: Elizabeth, John 
    Eyes Color: "Brown" 
    Hair Color: NULL 
    Result: John 
    Eyes Color: NULL 
    Hair Color: "Blonde" 
    Result: Elizabeth 
    Eyes Color: NULL 
    Hair Color: "Black" 
    Result: John 
    Eyes Color: "Blue" 
    Hair Color: "Black" 
    Result: John 
    Eyes Color: "Blue" 
    Hair Color: "Blonde" 
    Result: Elizabeth 
    Eyes Color: "Brown" 
    Hair Color: "Blonde" 
    Result: - 
    Eyes Color: "Brown" 
    Hair Color: "Black" 
    Result: John 
    

    我的第一个问题是过滤。第二个问题是在递归中过滤不分析节点是否包含节点的子节点。

    递归:

    with livelliRec 
    as 
    (
        select 
        0 as level, nodeid, parentid 
        from nodes 
    
        union all 
    
        select 
        livellirec.level+1, nodes.nodeid, nodes.parentid 
        from nodes 
        join livelliRec on nodes.parentid = livellirec.nodeid 
    ) 
    

    我发现了一个可能的解决方案列出所有可能的项目,当一个节点未配置为组,然后验证所有choosen项目在可能的项目。但如何编写查询来执行它?

    在此先感谢。

    +0

    是否应父节点被选择? –

    +0

    是的,它可以。每个节点都可以配置。这是错误的,相反:我不包括不包含父节点的孩子 – Emanuele

    回答

    0

    在我的例子,如果节点未配置为组,它会被选中:如果子节点没有choosen

    ;WITH Filtered AS (
        SELECT N.Id, N.ParentId 
        FROM nodes N 
        WHERE NOT EXISTS (
         SELECT 1 
         FROM configurations  C 
         INNER JOIN Options  C_OP ON C_OP.OptionId = C.OptionId 
         INNER JOIN Options  CH_OP ON CH_OP.GroupId = C_OP.GroupId 
         INNER JOIN Choises  CH ON CH.OptionId = CH_OP.OptionId 
         WHERE C.NodeId = N.Id AND CH.OptionId <> C.OptionId 
        ) 
    ), cte AS (
        SELECT 0 AS Level, Id, ParentId 
        FROM Filtered 
        WHERE ParentId IS NULL 
    
        UNION ALL 
    
        SELECT cte.Level + 1 AS Level, Id, ParentId 
        FROM Filtered F 
        INNER JOIN cte ON F.ParentId = cte.Id 
    ) 
    SELECT DISTINCT cte.Id 
    FROM cte 
    
    +0

    首先感谢您的帮助。我正在阅读解决方案,正如我所说,我的第一个问题是如何过滤。你选择了OR条件。我会问什么情况发生 眼睛颜色:“棕色” 发色:“金发” 结果: - ?也许结果将是“伊丽莎白”? – Emanuele

    +0

    呵呵,我现在明白了这个问题... –

    +0

    我现在就试试。我编辑了我的第一篇文章,在选项表中解释NULL。你可以编辑你的答案考虑Choices as table吗?再次感谢 – Emanuele