SQL - 获取层次结构的单个分支
SQL - Getting a single branch of a hierarchy
我有以下 table "x" 层级属性:
+-----------+--------+--------------+-----------+-------------+
| row | value | displayvalue | parentrow | parentvalue |
+-----------+--------+--------------+-----------+-------------+
| HIE1 | VALUE3 | value 3 | NULL | NULL |
| HIE2 | VALUE1 | value 11 | HIE1 | VALUE1 |
| HIE2 | VALUE1 | value 21 | HIE1 | VALUE2 |
| HIE2 | VALUE1 | value 31 | HIE1 | VALUE3 |
| HIE3 | VALUE1 | value 111 | HIE2 | VALUE1 |
| HIE3 | VALUE1 | value 311 | HIE2 | VALUE1 |
| HIE3 | VALUE1 | value 221 | HIE2 | VALUE2 |
+-----------+--------+--------------+-----------+-------------+
这只是一个示例 - 层次结构可能更大或更小,并且行代码不必是数字。我该如何提取这个 table 中唯一正确的分支?即:
+-----------+--------+--------------+-----------+-------------+
| row | value | displayvalue | parentrow | parentvalue |
+-----------+--------+--------------+-----------+-------------+
| HIE1 | VALUE3 | value 3 | NULL | NULL |
| HIE2 | VALUE1 | value 31 | HIE1 | VALUE3 |
| HIE3 | VALUE1 | value 311 | HIE2 | VALUE1 |
+-----------+--------+--------------+-----------+-------------+
这需要递归,我试过了:
With Attrs AS (
SELECT "row",
"value",
"displayvalue",
"parentrow",
"parentvalue",
FROM x
UNION ALL
SELECT child."row",
child."value",
child."displayvalue",
child."parentrow",
child."parentvalue",
FROM x child
JOIN Attrs ON child."parentrow" = Attrs."row" AND child."parentvalue" = Attrs."value"
WHERE Attrs."parentrow" IS NOT NULL
)
SELECT "row", "value", "displayvalue", "parentrow", "parentvalue"
FROM Attrs;
但这似乎扩大了结果池,而不是缩小了范围。我做错了什么?
编辑
忘记在 table 中添加序列列。这些是额外的条目:
+-----------+--------+-----------+
| row | seqno | parentseq |
+-----------+--------+-----------+
| HIE1 | 3 | NULL |
| HIE2 | 10 | 1 |
| HIE2 | 13 | 2 |
| HIE2 | 11 | 3 |
| HIE3 | 15 | 10 |
| HIE3 | 16 | 11 |
| HIE3 | 17 | 12 |
+-----------+--------+-----------+
所需的行将具有:
+-----------+--------+-----------+
| row | seqno | parentseq |
+-----------+--------+-----------+
| HIE1 | 3 | NULL |
| HIE2 | 11 | 3 |
| HIE3 | 16 | 11 |
+-----------+--------+-----------+
您可以使用以下查询:
;WITH Attrs AS (
-- Anchor query: Get the root records
SELECT row, value, displayvalue, parentrow, parentvalue
FROM x
WHERE parentrow IS NULL
UNION ALL
-- Recursive query: Get the records of the next level
SELECT child.row, child.value, child.displayvalue, child.parentrow, child.parentvalue
FROM x AS child
INNER JOIN Attrs AS parent
ON child.parentrow = parent.row AND child.parentvalue = parent.value
)
SELECT row, value, displayvalue, parentrow, parentvalue
FROM Attrs
递归 CTE
的第一个子查询,也称为 anchor 查询,获取层次结构的根记录。因此,您必须在此子查询上放置 parentrow IS NULL
。
第二个子查询将 table 与上一个递归的结果连接起来,以获取树层次结构中下一级的记录。不需要在此子查询中使用 parentrow IS NULL
,因为第一次执行递归产生的记录 已经 根节点记录。
编辑: 将序列号添加到我们得到的查询中:
;WITH Attrs AS (
-- Anchor query: Get the root records
SELECT row, seqno, value, displayvalue,
parentrow, parentvalue, parentseq
FROM x
WHERE parentrow IS NULL
UNION ALL
-- Recursive query: Get the records of the next level
SELECT child.row, child.seqno, child.value, child.displayvalue,
child.parentrow, child.parentvalue, child.parentseq
FROM x AS child
INNER JOIN Attrs AS parent
ON child.parentrow = parent.row AND
child.parentvalue = parent.value AND
child.parentseq = parent.seqno
)
SELECT row, value, displayvalue, parentrow, parentvalue
FROM Attrs
我有以下 table "x" 层级属性:
+-----------+--------+--------------+-----------+-------------+
| row | value | displayvalue | parentrow | parentvalue |
+-----------+--------+--------------+-----------+-------------+
| HIE1 | VALUE3 | value 3 | NULL | NULL |
| HIE2 | VALUE1 | value 11 | HIE1 | VALUE1 |
| HIE2 | VALUE1 | value 21 | HIE1 | VALUE2 |
| HIE2 | VALUE1 | value 31 | HIE1 | VALUE3 |
| HIE3 | VALUE1 | value 111 | HIE2 | VALUE1 |
| HIE3 | VALUE1 | value 311 | HIE2 | VALUE1 |
| HIE3 | VALUE1 | value 221 | HIE2 | VALUE2 |
+-----------+--------+--------------+-----------+-------------+
这只是一个示例 - 层次结构可能更大或更小,并且行代码不必是数字。我该如何提取这个 table 中唯一正确的分支?即:
+-----------+--------+--------------+-----------+-------------+
| row | value | displayvalue | parentrow | parentvalue |
+-----------+--------+--------------+-----------+-------------+
| HIE1 | VALUE3 | value 3 | NULL | NULL |
| HIE2 | VALUE1 | value 31 | HIE1 | VALUE3 |
| HIE3 | VALUE1 | value 311 | HIE2 | VALUE1 |
+-----------+--------+--------------+-----------+-------------+
这需要递归,我试过了:
With Attrs AS (
SELECT "row",
"value",
"displayvalue",
"parentrow",
"parentvalue",
FROM x
UNION ALL
SELECT child."row",
child."value",
child."displayvalue",
child."parentrow",
child."parentvalue",
FROM x child
JOIN Attrs ON child."parentrow" = Attrs."row" AND child."parentvalue" = Attrs."value"
WHERE Attrs."parentrow" IS NOT NULL
)
SELECT "row", "value", "displayvalue", "parentrow", "parentvalue"
FROM Attrs;
但这似乎扩大了结果池,而不是缩小了范围。我做错了什么?
编辑
忘记在 table 中添加序列列。这些是额外的条目:
+-----------+--------+-----------+
| row | seqno | parentseq |
+-----------+--------+-----------+
| HIE1 | 3 | NULL |
| HIE2 | 10 | 1 |
| HIE2 | 13 | 2 |
| HIE2 | 11 | 3 |
| HIE3 | 15 | 10 |
| HIE3 | 16 | 11 |
| HIE3 | 17 | 12 |
+-----------+--------+-----------+
所需的行将具有:
+-----------+--------+-----------+
| row | seqno | parentseq |
+-----------+--------+-----------+
| HIE1 | 3 | NULL |
| HIE2 | 11 | 3 |
| HIE3 | 16 | 11 |
+-----------+--------+-----------+
您可以使用以下查询:
;WITH Attrs AS (
-- Anchor query: Get the root records
SELECT row, value, displayvalue, parentrow, parentvalue
FROM x
WHERE parentrow IS NULL
UNION ALL
-- Recursive query: Get the records of the next level
SELECT child.row, child.value, child.displayvalue, child.parentrow, child.parentvalue
FROM x AS child
INNER JOIN Attrs AS parent
ON child.parentrow = parent.row AND child.parentvalue = parent.value
)
SELECT row, value, displayvalue, parentrow, parentvalue
FROM Attrs
递归 CTE
的第一个子查询,也称为 anchor 查询,获取层次结构的根记录。因此,您必须在此子查询上放置 parentrow IS NULL
。
第二个子查询将 table 与上一个递归的结果连接起来,以获取树层次结构中下一级的记录。不需要在此子查询中使用 parentrow IS NULL
,因为第一次执行递归产生的记录 已经 根节点记录。
编辑: 将序列号添加到我们得到的查询中:
;WITH Attrs AS (
-- Anchor query: Get the root records
SELECT row, seqno, value, displayvalue,
parentrow, parentvalue, parentseq
FROM x
WHERE parentrow IS NULL
UNION ALL
-- Recursive query: Get the records of the next level
SELECT child.row, child.seqno, child.value, child.displayvalue,
child.parentrow, child.parentvalue, child.parentseq
FROM x AS child
INNER JOIN Attrs AS parent
ON child.parentrow = parent.row AND
child.parentvalue = parent.value AND
child.parentseq = parent.seqno
)
SELECT row, value, displayvalue, parentrow, parentvalue
FROM Attrs