gpt4 book ai didi

SQL 树向下遍历到根并备份一个

转载 作者:行者123 更新时间:2023-12-01 01:13:34 27 4
gpt4 key购买 nike

我有下表(ObjectStates)并且想要获得根以及根的第一个 child :

ID    Title    ParentID
1 Draft null
2 Green null
3 Red null
4 Foo 1
5 Bar 4
6 Some1 1
7 Some2 6
8 XYZ 2
9 Some3 7

我想要以下输出:
GetState(5)
-- returns root: 1, first-child: 4
GetState(6)
-- returns root: 1, first-child: 6
GetState(7)
-- returns root: 1, first-child: 6
GetState(9)
-- returns root: 1, first-child: 6
GetState(8)
-- returns root: 2, first-child: 8

所以无论我查询的层次结构有多深 - 我总是想要根元素以及第一个子元素。如果你考虑这棵树,我总是想要红色和蓝色元素,无论我在树中有多深。

enter image description here

我可以像这样获得“根”状态:
WITH CTEHierarchy
AS (
SELECT
ID
,0 AS LEVEL
,ID AS root

FROM ObjectStates
WHERE ParentID IS NULL

UNION ALL

SELECT
ObjectStates.ID
,LEVEL + 1 AS LEVEL
,[root]

FROM ObjectStates
INNER JOIN CTEHierarchy uh ON uh.id = ObjectStates.ParentID
)
SELECT [root]
FROM CTEHierarchy
WHERE ID = @ObjectStateID

这给了我想要的根结果:
GetState(5)
-- returns root: 1
GetState(9)
-- returns root: 1
GetState(2)
-- returns root: 2

我怎样才能从那里向上穿越?那么从根获取树中的下一个 child ?或者反过来 - 获得根以及第一级。递归让我头疼。

最佳答案

我今天正在使用这个查询来遍历主键外键关系以跟踪整个路径,这个问题似乎很相似。所以只需粘贴相同的代码。您可以直接运行此代码并检查这是否是您需要的。

此查询在 CTE 中添加了另外两列,即 Hops 和 Path,其中 Hops 是元素级别,Path 是从头到尾遍历的节点。

WITH cte
AS
(
SELECT
fk.create_date
, fk.modify_date
, fkc.constraint_object_id AS ConstraintId
, OBJECT_NAME(fkc.constraint_object_id) AS ConstraintName
, OBJECT_NAME(fkc.referenced_object_id) AS PrimaryKeyTableName
, rc.name AS PrimaryKeyColumnName
, OBJECT_NAME(fk.parent_object_id) AS ForeignKeyTableName
, lc.name AS ForeignKeyColumnName
FROM sys.foreign_key_columns fkc
INNER JOIN sys.columns rc
ON rc.OBJECT_ID = fkc.referenced_object_id
AND fkc.referenced_column_id = rc.column_id
INNER JOIN sys.foreign_keys fk
ON fk.OBJECT_ID = fkc.constraint_object_id
INNER JOIN sys.columns lc
ON lc.OBJECT_ID = fk.parent_object_id
AND fkc.parent_column_id = lc.column_id
)
, cte2(create_date, modify_date, ConstraintName
, PrimaryKeyTableName, PrimaryKeyColumnName
, ForeignKeyTableName, ForeignKeyColumnName
, Hops, path ) AS
(
SELECT
create_date, modify_date, ConstraintName
, PrimaryKeyTableName, PrimaryKeyColumnName
, ForeignKeyTableName, ForeignKeyColumnName
, 1 , CAST(QUOTENAME(PrimaryKeyTableName + '.' + PrimaryKeyColumnName) AS VARCHAR(4000))
FROM cte
UNION ALL
SELECT
cte.create_date, cte.modify_date, cte.ConstraintName
, cte.PrimaryKeyTableName, cte.PrimaryKeyColumnName
, cte.ForeignKeyTableName, cte.ForeignKeyColumnName
, cte2.Hops +1, CAST(cte2.path + '-> ' +QUOTENAME(cte.PrimaryKeyTableName+ '.' + cte.PrimaryKeyColumnName) AS VARCHAR(4000))
FROM cte2 INNER JOIN cte ON cte2.ForeignKeyTableName = cte.PrimaryKeyTableName
AND cte2.ForeignKeyColumnName != cte.PrimaryKeyColumnName
)
SELECT
ConstraintName
, PrimaryKeyTableName, PrimaryKeyColumnName
, ForeignKeyTableName, ForeignKeyColumnName
, Hops, path + '-> ' + QUOTENAME(ForeignKeyTableName + '.' + ForeignKeyColumnName) AS Path
FROM cte2

仅当数据库中物理存在外键约束时,此查询才有效。

关于SQL 树向下遍历到根并备份一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13585460/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com