approche normale hiérarchique STR (ItemOrder, 4) :
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)
Query:
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
sortie:
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)
Maintenant, nous allons outrepasser le tri sur les gestionnaires de projet de groupe, faisons Chef de projet 2 viennent avant 1, et chef de projet 1 viennent après Chef de projet 2. Faisons également tester 4 est avant 3 et testeur 3 vient après testeur 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
requête:
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
sortie:
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)
Wi Thout la colonne de tri en projection de données:
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
Sortie:
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)
Project Manager 2 est avant Project Manager 1. Tester 4 est avant testeur 3
La technique réside dans la substitution de texte numérique pour b.name s'il y a un order_override (non nul):
sort || ' : ' || coalesce(lpad(order_override::text, 10, '0'), b.emp_name)
Ab Code Ove est Postgres, de se convertir à Sql Server, supprimer le mot RECURSIVE
, changer REPEAT
-REPLICATE
, ||
-+
.
équivalent de ...
lpad(order_override::text, 10, '0')
... est:
RIGHT(REPLICATE('0',10) + CONVERT(VARCHAR, order_override), 10)
Pouvez-vous être plus sepcific de l'ordre? N'ajoute pas 'ORDER BY ItemOrder' au travail SELECT de niveau supérieur? – mdma
J'ai moi-même eu du mal avec ça - vous pouvez commander par de nombreuses choses - le MenuItemId, le niveau dans la hiérarchie et quelques autres - mais je n'ai jamais trouvé de manière satisfaisante en T-SQL pour que les enfants viennent après leurs parents, plusieurs niveaux profonds. Je suis impatient de voir si quelqu'un ici a une bonne idée - bonne question! –
une autre (pour moi) solution de travail [là] (https://stackoverflow.com/a/18771942/3588062) avec HIERARCHYID (travaillant à partir de SQL Server 2008 R2) –