我有一个表示地图的连接节点表,这些节点有各自的from和to节,指定它们的连接方式:
< - >从 - NODENUMBER1 - 到 - 从 - NODENUMBER2 - 到
我正在运行一些测试试图从这个地图中删除部分,我想选择一个节点来删除它下游的所有节点。
我想知道如何通过SQL查询来实现这一点,例如这个伪SQL:
select A.nodes from node_table A, node_table B
where A.to_section = B.from_section
and **A.starting_node = NODENUMBER_X**;
因此,通过设置NODENUMBER_X,查询将生成连接到NODENUMBER_X下游的所有节点。
答案 0 :(得分:0)
递归并不总是很有效率,但它是解决此类问题的一种方法。假设node_table具有唯一字段node_id(int):
declare @start_node_id int, @loop_limit int, @loop_count int;
set @start_node_id = 1234; -- Insert the node ID you want to start from.
set @loop_limit = 1000; -- Set a limit on the number of loop iterations.
set @loop_count = 0;
create table #NODES_TO_DELETE(NODE_ID int);
-- Get first child nodes, directly linked to start node.
insert into #NODES_TO_DELETE(NODE_ID)
select A.NODE_ID
from node_table A inner join node_table B on B.from_section = A.to_section
where B.NODE_ID = @start_node_id;
-- If there are child nodes not yet in our temp table, continue loop.
WHILE EXISTS(select 1
from node_table A inner join node_table B on B.from_section = A.to_section
inner join #NODES_TO_DELETE D on B.NODE_ID = D.NODE_ID
left join #NODES_TO_DELETE X on A.NODE_ID = X.NODE_ID
where X.NODE_ID is null) and
@loop_count < @loop_limit
BEGIN
-- Add child nodes to temp table. Avoid duplicate IDs.
insert into #NODES_TO_DELETE(NODE_ID)
select distinct A.NODE_ID
from node_table A inner join node_table B on B.from_section = A.to_section
inner join #NODES_TO_DELETE D on B.NODE_ID = D.NODE_ID
left join #NODES_TO_DELETE X on A.NODE_ID = X.NODE_ID
where X.NODE_ID is null;
-- Increment loop count.
set @loop_count = @loop_count + 1;
END
IF @loop_count > @loop_limit
print 'Loop limit exceeded.'; -- We've exceeded our loop limit. May not have all matches.
ELSE
delete N -- Delete all nodes inserted into our temp table.
from node_table N
inner join #NODES_TO_DELETE D on N.NODE_ID = D.NODE_ID;
drop table #NODES_TO_DELETE;