使用 T-SQL 在分层数据中查找特定父级
Find a specific parent inside hierarchical data using T-SQL
我得到了具有层次结构顺序的对象。每个对象都有一个 ID、一个父对象(table 中的TO_ID
)和一个类型。
我的数据在 table 中,如下所示:
ID | TO_ID | TYPE
123 | 103 | group
176 | 103 | field
256 | 169 | group
103 | 234 | organization
234 | 390 | site
现在我想搜索 table 直到找到具有特定类型的父对象(我不知道我的起始对象有多少个父对象)。
比如我从ID
123
开始,想找到TYPE
site
.[=18=的父对象ID
]
如何用 SQL 解决这个问题?
为此您需要递归 CTE:
DECLARE @t TABLE (ID INT, TO_ID INT, TYPE VARCHAR(100));
INSERT INTO @t VALUES
(123, 103, 'group'),
(176, 103, 'field'),
(256, 169, 'group'),
(103, 234, 'organization'),
(234, 390, 'site'),
(390, 999, 'notme');
DECLARE @start INT = 123;
DECLARE @stop VARCHAR(100) = 'site';
WITH cte AS (
SELECT base.*, 1 AS LVL
FROM @t base
WHERE ID = @start
UNION ALL
SELECT curr.*, LVL + 1
FROM @t curr
INNER JOIN cte prev ON curr.ID = prev.TO_ID
WHERE prev.TYPE <> @stop
)
SELECT *
FROM cte
ORDER BY LVL
递归CTE实际上是一个迭代查询。您从一些行(第 123 行)开始,然后将行附加到上一次迭代的结果,直到满足某些条件(您 运行 超出行或在上一次迭代中找到 site
)。这是结果:
ID | TO_ID | TYPE | LVL
123 | 103 | group | 1
103 | 234 | organization | 2
234 | 390 | site | 3
如果您对查找两个节点之间的完整路径不感兴趣,请从 curr 中删除 where 子句并在最后添加 WHERE TYPE = site
。
我得到了具有层次结构顺序的对象。每个对象都有一个 ID、一个父对象(table 中的TO_ID
)和一个类型。
我的数据在 table 中,如下所示:
ID | TO_ID | TYPE
123 | 103 | group
176 | 103 | field
256 | 169 | group
103 | 234 | organization
234 | 390 | site
现在我想搜索 table 直到找到具有特定类型的父对象(我不知道我的起始对象有多少个父对象)。
比如我从ID
123
开始,想找到TYPE
site
.[=18=的父对象ID
]
如何用 SQL 解决这个问题?
为此您需要递归 CTE:
DECLARE @t TABLE (ID INT, TO_ID INT, TYPE VARCHAR(100));
INSERT INTO @t VALUES
(123, 103, 'group'),
(176, 103, 'field'),
(256, 169, 'group'),
(103, 234, 'organization'),
(234, 390, 'site'),
(390, 999, 'notme');
DECLARE @start INT = 123;
DECLARE @stop VARCHAR(100) = 'site';
WITH cte AS (
SELECT base.*, 1 AS LVL
FROM @t base
WHERE ID = @start
UNION ALL
SELECT curr.*, LVL + 1
FROM @t curr
INNER JOIN cte prev ON curr.ID = prev.TO_ID
WHERE prev.TYPE <> @stop
)
SELECT *
FROM cte
ORDER BY LVL
递归CTE实际上是一个迭代查询。您从一些行(第 123 行)开始,然后将行附加到上一次迭代的结果,直到满足某些条件(您 运行 超出行或在上一次迭代中找到 site
)。这是结果:
ID | TO_ID | TYPE | LVL
123 | 103 | group | 1
103 | 234 | organization | 2
234 | 390 | site | 3
如果您对查找两个节点之间的完整路径不感兴趣,请从 curr 中删除 where 子句并在最后添加 WHERE TYPE = site
。