过滤递归 sql 查询与可能的和选择的项目相交
Filtering recursive sql query intersecting possible and choosen items
在Sql服务器中我有以下场景:
选项和相关组:
Groups(Id, Description)
Options(Id, GroupId, Description)
配置了选项的节点:
Nodes(Id, ParentNodeId, Description)
Configurations(Id, NodeId, OptionId)
所以一个节点可以有一个或多个选项,但每组一个
用户选择:
Choices (Guid, OptionId)
在输出中,我希望以递归方式使用选择选项配置节点。
例如:
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
)
我找到了一个可能的解决方案,当一个节点没有为该组配置时列出所有可能的项目,然后验证所有选择的项目都在可能的项目中。但是如何编写查询来执行呢?
提前致谢。
在我的示例中,如果没有为组配置节点,它将被选中:
;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
在Sql服务器中我有以下场景:
选项和相关组:
Groups(Id, Description) Options(Id, GroupId, Description)
配置了选项的节点:
Nodes(Id, ParentNodeId, Description) Configurations(Id, NodeId, OptionId)
所以一个节点可以有一个或多个选项,但每组一个
用户选择:
Choices (Guid, OptionId)
在输出中,我希望以递归方式使用选择选项配置节点。 例如:
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
)
我找到了一个可能的解决方案,当一个节点没有为该组配置时列出所有可能的项目,然后验证所有选择的项目都在可能的项目中。但是如何编写查询来执行呢?
提前致谢。
在我的示例中,如果没有为组配置节点,它将被选中:
;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