Return 所有子记录的最深祖先的特定列
Return a specific column of the deepest ancestor for all child records
我正在研究 SQL 服务器中的递归。
我有以下查询,但我似乎无法让它执行我想要的操作。
;WITH cte_txn AS (
SELECT
vth_id,
vth_pol_id,
vth_moved_from_vth_id
FROM Variant_Transaction_Header
UNION ALL
SELECT
e.vth_id,
e.vth_pol_id,
e.vth_moved_from_vth_id
FROM Variant_Transaction_Header e
JOIN cte_txn ON cte_txn.vth_moved_from_vth_id = e.vth_id
)
SELECT * FROM cte_txn;
如果我在锚点中指定 vth_id(在本例中为“WHERE vth_id = 72418”),我会得到以下信息:
vth_id vth_pol_id vth_moved_from_vth_id
72418 NULL 57019
57019 NULL 53518
53518 803 NULL
太棒了。但是现在我想把上面的数据转换成:
vth_id vth_pol_id vth_moved_from_vth_id
72418 803 57019
57019 803 53518
53518 803 NULL
换句话说,我想要DEEPEST祖先的vth_pol_id,无论我插入哪个vth_id。
执行此操作的最佳方法是什么?
编辑:
我应该指定我想要得到一个包含所有分支的结果集,vth_pol_id 本质上表示每个记录在哪个分支上。
我试图从后代变成祖先。
另一种方法更可取,因为我需要父记录中的一个值来与子记录一起使用。
这是更新后的表达式:
;WITH cte_txn AS (
SELECT
vth_id,
vth_pol_id,
vth_moved_from_vth_id
FROM Variant_Transaction_Header
/*start at the base of the branch instead of the end.*/
WHERE NOT vth_pol_id IS NULL
UNION ALL
SELECT
e.vth_id,
/* use parent's vth_pol_id */
cte_txn.vth_pol_id,
e.vth_moved_from_vth_id
FROM Variant_Transaction_Header e
/* Move away from ancestor instead of toward. */
JOIN cte_txn ON cte_txn.vth_id = e.vth_moved_from_vth_id
WHERE cte_txn.vth_id <> e.vth_id
)
/* Join again with vth for all records */
SELECT
v.vth_id,
c.vth_pol_id,
v.vth_moved_from_vth_id
FROM Variant_Transaction_Header v
LEFT OUTER JOIN cte_txn c ON c.vth_id = v.vth_id
外连接是为了确保如果根节点恰好在vth_pol_id列中有空值,仍然返回所有记录。
越简单的:
SELECT * FROM cte_txn;
如果要省略此类记录,可以使用。
我正在研究 SQL 服务器中的递归。 我有以下查询,但我似乎无法让它执行我想要的操作。
;WITH cte_txn AS (
SELECT
vth_id,
vth_pol_id,
vth_moved_from_vth_id
FROM Variant_Transaction_Header
UNION ALL
SELECT
e.vth_id,
e.vth_pol_id,
e.vth_moved_from_vth_id
FROM Variant_Transaction_Header e
JOIN cte_txn ON cte_txn.vth_moved_from_vth_id = e.vth_id
)
SELECT * FROM cte_txn;
如果我在锚点中指定 vth_id(在本例中为“WHERE vth_id = 72418”),我会得到以下信息:
vth_id vth_pol_id vth_moved_from_vth_id
72418 NULL 57019
57019 NULL 53518
53518 803 NULL
太棒了。但是现在我想把上面的数据转换成:
vth_id vth_pol_id vth_moved_from_vth_id
72418 803 57019
57019 803 53518
53518 803 NULL
换句话说,我想要DEEPEST祖先的vth_pol_id,无论我插入哪个vth_id。 执行此操作的最佳方法是什么?
编辑: 我应该指定我想要得到一个包含所有分支的结果集,vth_pol_id 本质上表示每个记录在哪个分支上。
我试图从后代变成祖先。 另一种方法更可取,因为我需要父记录中的一个值来与子记录一起使用。 这是更新后的表达式:
;WITH cte_txn AS (
SELECT
vth_id,
vth_pol_id,
vth_moved_from_vth_id
FROM Variant_Transaction_Header
/*start at the base of the branch instead of the end.*/
WHERE NOT vth_pol_id IS NULL
UNION ALL
SELECT
e.vth_id,
/* use parent's vth_pol_id */
cte_txn.vth_pol_id,
e.vth_moved_from_vth_id
FROM Variant_Transaction_Header e
/* Move away from ancestor instead of toward. */
JOIN cte_txn ON cte_txn.vth_id = e.vth_moved_from_vth_id
WHERE cte_txn.vth_id <> e.vth_id
)
/* Join again with vth for all records */
SELECT
v.vth_id,
c.vth_pol_id,
v.vth_moved_from_vth_id
FROM Variant_Transaction_Header v
LEFT OUTER JOIN cte_txn c ON c.vth_id = v.vth_id
外连接是为了确保如果根节点恰好在vth_pol_id列中有空值,仍然返回所有记录。 越简单的:
SELECT * FROM cte_txn;
如果要省略此类记录,可以使用。