Bạn có thể làm cho việc tìm kiếm đường dẫn hiệu quả hơn nếu bạn bắt đầu từ cuối. Bắt đầu từ trẻ em. Nếu bạn bắt đầu từ cha mẹ, nó đòi hỏi phải đi ngang qua tất cả các con; trong khi nếu bạn tìm kiếm từ con, nó chỉ có một cha mẹ, do đó sẽ không lãng phí thời gian để tìm đường dẫn giữa nguồn và đích.
with recursive find_parent(source, target, recentness) as
(
select source, target, 0
from tbl
where target = 9
union all
select i.source, i.target, fp.recentness + 1
from tbl i
join find_parent fp on i.target = fp.source
),
construct_path(source, target, recentness, path) as
(
select source, target, recentness, source || '.' || target
from find_parent
where recentness = (select max(recentness) from find_parent)
union
select dd.source, dd.target, dd.recentness, cp.path || '.' || dd.target
from find_parent dd
join construct_path cp on dd.recentness = cp.recentness - 1
)
select source, target, path
from construct_path
order by recentness desc
Đầu ra:
SOURCE TARGET PATH
1 2 1.2
2 4 1.2.4
4 9 1.2.4.9
Kiểm tra trực tiếp:http://www.sqlfiddle.com/#!1/13e6b/1
Tương tự như thế này:Làm thế nào để lấy cha mẹ cho một con trong SQL SERVER 2005
Điều này được tối ưu hóa, cắt đệ quy cho cha mẹ nếu nó đã tìm thấy một (nguồn) cụ thể.
Nguồn =2
Mục tiêu =9
with recursive find_parent(source, target, recentness) as
(
select source, target, 0
from tbl
where target = 9
union all
select i.source, i.target, fp.recentness + 1
from tbl i
join find_parent fp on i.target = fp.source
-- despite the name, this target is another one's source
and i.target <> 2
)
,construct_path(source, target, recentness, path) as
(
select source, target, recentness, source || '.' || target
from find_parent
where recentness = (select max(recentness) from find_parent)
union
select dd.source, dd.target, dd.recentness, cp.path || '.' || dd.target
from find_parent dd
join construct_path cp on dd.recentness = cp.recentness - 1
)
select source, target, path
from construct_path
order by recentness desc
Đầu ra:
SOURCE TARGET PATH
2 4 2.4
4 9 2.4.9
Kiểm tra trực tiếp:http://www.sqlfiddle.com/#!1/13e6b/16