Ram*_*ona 4 sql t-sql sql-server hierarchical-data
我有按层次结构排列的对象。每个对象都有一个ID,一个父对象(TO_ID
在表中)和一个类型。我的数据在一个如下表中:
ID | TO_ID | TYPE
123 | 103 | group
176 | 103 | field
256 | 169 | group
103 | 234 | organization
234 | 390 | site
Run Code Online (Sandbox Code Playgroud)
现在,我要搜索表,直到找到具有特定类型的父对象(我不知道我的起始对象有多少个父对象)。
例如,我以开头,ID
123
并希望通过找到ID
父对象的TYPE
site
。
如何使用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
Run Code Online (Sandbox Code Playgroud)
递归CTE实际上是一个迭代查询。您从一些行(第123行)开始,然后继续将行追加到上一个迭代的结果中,直到满足某些条件为止(您用完了行或site
在上一个迭代中找到了行)。结果如下:
ID | TO_ID | TYPE | LVL
123 | 103 | group | 1
103 | 234 | organization | 2
234 | 390 | site | 3
Run Code Online (Sandbox Code Playgroud)
如果您对查找两个节点之间的完整路径不感兴趣,请从curr中删除where子句,并WHERE TYPE = site
在最后添加。