通常の階層的アプローチ:
select *
into emp
from
(values
(1, 'President', NULL),
(2, 'Vice President', 1),
(3, 'CEO', 2),
(4, 'CTO', 2),
(5, 'Group Project Manager', 4),
(6, 'Project Manager 1', 5),
(7, 'Project Manager 2', 5),
(8, 'Team Leader 1', 6),
(9, 'Software Engineer 1', 8),
(10, 'Software Engineer 2', 8),
(11, 'Test Lead 1', 6),
(12, 'Tester 1', 11),
(13, 'Tester 2', 11),
(14, 'Team Leader 2', 7),
(15, 'Software Engineer 3', 14),
(16, 'Software Engineer 4', 14),
(17, 'Test Lead 2', 7),
(18, 'Tester 3', 17),
(19, 'Tester 4', 17),
(20, 'Tester 5', 17)
) as x(emp_id, emp_name, mgr_id)
クエリ:
with recursive org(emp_id, emp_name, emp_level, mgr_id, sort) as
(
select
a.emp_id, a.emp_name, 0, a.mgr_id,
a.emp_name
from emp a
where a.mgr_id is null
union all
select
b.emp_id, b.emp_name, emp_level + 1, b.mgr_id,
sort || ' : ' || b.emp_name
from emp b
join org on org.emp_id = b.mgr_id
)
select
emp_id, repeat(' ', emp_level * 2) || emp_name as emp_name, sort
from org
order by sort
出力:
emp_id | emp_name | sort
--------+---------------------------------+--------------------------------------------------------------------------------------------------------------------
1 | President | President
2 | Vice President | President : Vice President
3 | CEO | President : Vice President : CEO
4 | CTO | President : Vice President : CTO
5 | Group Project Manager | President : Vice President : CTO : Group Project Manager
6 | Project Manager 1 | President : Vice President : CTO : Group Project Manager : Project Manager 1
8 | Team Leader 1 | President : Vice President : CTO : Group Project Manager : Project Manager 1 : Team Leader 1
9 | Software Engineer 1 | President : Vice President : CTO : Group Project Manager : Project Manager 1 : Team Leader 1 : Software Engineer 1
10 | Software Engineer 2 | President : Vice President : CTO : Group Project Manager : Project Manager 1 : Team Leader 1 : Software Engineer 2
11 | Test Lead 1 | President : Vice President : CTO : Group Project Manager : Project Manager 1 : Test Lead 1
12 | Tester 1 | President : Vice President : CTO : Group Project Manager : Project Manager 1 : Test Lead 1 : Tester 1
13 | Tester 2 | President : Vice President : CTO : Group Project Manager : Project Manager 1 : Test Lead 1 : Tester 2
7 | Project Manager 2 | President : Vice President : CTO : Group Project Manager : Project Manager 2
14 | Team Leader 2 | President : Vice President : CTO : Group Project Manager : Project Manager 2 : Team Leader 2
15 | Software Engineer 3 | President : Vice President : CTO : Group Project Manager : Project Manager 2 : Team Leader 2 : Software Engineer 3
16 | Software Engineer 4 | President : Vice President : CTO : Group Project Manager : Project Manager 2 : Team Leader 2 : Software Engineer 4
17 | Test Lead 2 | President : Vice President : CTO : Group Project Manager : Project Manager 2 : Test Lead 2
18 | Tester 3 | President : Vice President : CTO : Group Project Manager : Project Manager 2 : Test Lead 2 : Tester 3
19 | Tester 4 | President : Vice President : CTO : Group Project Manager : Project Manager 2 : Test Lead 2 : Tester 4
20 | Tester 5 | President : Vice President : CTO : Group Project Manager : Project Manager 2 : Test Lead 2 : Tester 5
(20 rows)
次に、グループ プロジェクト マネージャーの並べ替えをオーバーライドし、プロジェクト マネージャー 2 をプロジェクト マネージャー 1 の前に配置し、プロジェクト マネージャー 1 をプロジェクト マネージャー 2 の後に配置します。また、テスター 4 を 3 の前に配置し、テスター 3 をテスター 4 の後に配置します。
alter table emp add column order_override int null;
update emp set order_override = 1 where emp_id = 7; -- PM 2
update emp set order_override = 2 where emp_id = 6; -- PM 1
update emp set order_override = 1 where emp_id = 19; -- Tester 4
update emp set order_override = 2 where emp_id = 18; -- Tester 3
クエリ:
with recursive org(emp_id, emp_name, emp_level, mgr_id, sort) as
(
select
a.emp_id, a.emp_name, 0, a.mgr_id,
a.emp_name
from emp a
where a.mgr_id is null
union all
select
b.emp_id, b.emp_name, emp_level + 1, b.mgr_id,
sort || ' : ' || coalesce( lpad(order_override::text, 10, '0'), b.emp_name )
from emp b
join org on org.emp_id = b.mgr_id
)
select
emp_id, repeat(' ', emp_level * 2) || emp_name as emp_name, sort
from org
order by sort
出力:
emp_id | emp_name | sort
--------+---------------------------------+-------------------------------------------------------------------------------------------------------------
1 | President | President
2 | Vice President | President : Vice President
3 | CEO | President : Vice President : CEO
4 | CTO | President : Vice President : CTO
5 | Group Project Manager | President : Vice President : CTO : Group Project Manager
7 | Project Manager 2 | President : Vice President : CTO : Group Project Manager : 0000000001
14 | Team Leader 2 | President : Vice President : CTO : Group Project Manager : 0000000001 : Team Leader 2
15 | Software Engineer 3 | President : Vice President : CTO : Group Project Manager : 0000000001 : Team Leader 2 : Software Engineer 3
16 | Software Engineer 4 | President : Vice President : CTO : Group Project Manager : 0000000001 : Team Leader 2 : Software Engineer 4
17 | Test Lead 2 | President : Vice President : CTO : Group Project Manager : 0000000001 : Test Lead 2
19 | Tester 4 | President : Vice President : CTO : Group Project Manager : 0000000001 : Test Lead 2 : 0000000001
18 | Tester 3 | President : Vice President : CTO : Group Project Manager : 0000000001 : Test Lead 2 : 0000000002
20 | Tester 5 | President : Vice President : CTO : Group Project Manager : 0000000001 : Test Lead 2 : Tester 5
6 | Project Manager 1 | President : Vice President : CTO : Group Project Manager : 0000000002
8 | Team Leader 1 | President : Vice President : CTO : Group Project Manager : 0000000002 : Team Leader 1
9 | Software Engineer 1 | President : Vice President : CTO : Group Project Manager : 0000000002 : Team Leader 1 : Software Engineer 1
10 | Software Engineer 2 | President : Vice President : CTO : Group Project Manager : 0000000002 : Team Leader 1 : Software Engineer 2
11 | Test Lead 1 | President : Vice President : CTO : Group Project Manager : 0000000002 : Test Lead 1
12 | Tester 1 | President : Vice President : CTO : Group Project Manager : 0000000002 : Test Lead 1 : Tester 1
13 | Tester 2 | President : Vice President : CTO : Group Project Manager : 0000000002 : Test Lead 1 : Tester 2
(20 rows)
データ プロジェクションで並べ替え列を使用しない場合:
with recursive org(emp_id, emp_name, emp_level, mgr_id, sort) as
(
select
a.emp_id, a.emp_name, 0, a.mgr_id,
a.emp_name
from emp a
where a.mgr_id is null
union all
select
b.emp_id, b.emp_name, emp_level + 1, b.mgr_id,
sort || ' : ' || coalesce( lpad(order_override::text, 10, '0'), b.emp_name )
from emp b
join org on org.emp_id = b.mgr_id
)
select
emp_id, repeat(' ', emp_level * 2) || emp_name as emp_name
from org
order by sort
出力:
emp_id | emp_name
--------+---------------------------------
1 | President
2 | Vice President
3 | CEO
4 | CTO
5 | Group Project Manager
7 | Project Manager 2
14 | Team Leader 2
15 | Software Engineer 3
16 | Software Engineer 4
17 | Test Lead 2
19 | Tester 4
18 | Tester 3
20 | Tester 5
6 | Project Manager 1
8 | Team Leader 1
9 | Software Engineer 1
10 | Software Engineer 2
11 | Test Lead 1
12 | Tester 1
13 | Tester 2
(20 rows)
プロジェクト マネージャ 2 はプロジェクト マネージャ 1 の前に配置されます。テスター 4 はテスター 3 の前に配置されます。
order_override(null 以外) がある場合、テクニックは b.name の数値テキスト置換にあります。
sort || ' : ' || coalesce( lpad(order_override::text, 10, '0'), b.emp_name )
上記のコードは Postgres です。Sql Server に変換するには、単語を削除し、にRECURSIVE
変更REPEAT
します。REPLICATE
||
+
相当する...
lpad(order_override::text, 10, '0')
...は:
RIGHT( REPLICATE('0',10) + CONVERT(VARCHAR, order_override), 10)