首先,我們需要從兩個列有層次的聯繫完全作業列表:
select
all_jobs.job_id as jobstream,
job_depends.follow_jobstream as parent_jobstream
from
(
select jobstream job_id from job_list
union
select follow_jobstream job_id from job_list
) all_jobs,
job_list job_depends
where
job_depends.jobstream (+) = all_jobs.job_id
然後確定每個崗位的深度。
with full_job_list as (
select
all_jobs.job_id as jobstream,
job_depends.follow_jobstream as parent_jobstream
from
(
select jobstream job_id from job_list
union
select follow_jobstream job_id from job_list
) all_jobs,
job_list job_depends
where
job_depends.jobstream (+) = all_jobs.job_id
)
select
CONNECT_BY_ROOT jobstream as jobstream,
level as lvl,
CONNECT_BY_ROOT parent_jobstream as preceding_jobstream,
sys_connect_by_path(jobstream, '<-') as path_illustration
from
full_job_list
connect by
prior parent_jobstream = jobstream
最後根據深度安排工作。同一深度的作業可以按任意順序工作。
with full_job_list as (
select
all_jobs.job_id as jobstream,
job_depends.follow_jobstream as parent_jobstream
from
(
select jobstream job_id from job_list
union
select follow_jobstream job_id from job_list
) all_jobs,
job_list job_depends
where
job_depends.jobstream (+) = all_jobs.job_id
)
select
jobstream,
depth,
preceding_jobstream
from (
select distinct
jobstream,
(
last_value(lvl ignore nulls)
over (partition by jobstream
order by lvl
rows between unbounded preceding and unbounded following
)
) as depth,
(
last_value(preceding_jobstream ignore nulls)
over (partition by jobstream
order by lvl
rows between unbounded preceding and unbounded following
)
) as preceding_jobstream
from (
select
CONNECT_BY_ROOT jobstream as jobstream,
level as lvl,
CONNECT_BY_ROOT parent_jobstream as preceding_jobstream
from
full_job_list
connect by
prior parent_jobstream = jobstream
)
)
order by depth, jobstream
SQL Fiddle
更新糾正,以獲得完整的任務列表和添加前的工作。
Update2更正了路徑方向的錯誤。
開始遞歸CTE!你的例子中的 –
什麼jobstream會先運行? – ChrisCamp
@Goat_CO感謝您的提示! Oracle CTE有什麼好的資源? – TimeBomb006