I have tree structure based records(parent and child relationship) and I want to achieve nested level sort. Basically, I need level based sort as well as need to maintain the parent and child relationship(sort child level). I have tried using CTE, but I could achieve only level based sort but problem is can't achieve the parent and child relationship.
I tried below query
SELECT * FROM EMP WHERE PARENTID IS NULL order by
CASE WHEN PARENTID IS NULL THEN
lower(name)
ELSE
(SELECT lower(name) FROM EMP WHERE ID=ROOTID) END DESC,
ROOTID, JOBLEVEL, NAME
Actual TABLE
ID PARENTID NAME FULLPATH LEVEL ROOTID
_____________________________________________________________
1 NULL AA 1 1 1
2 1 BB 1.2 2 1
3 1 ZZ 1.3 2 1
4 1 HH 1.4 2 1
5 2 RR 1.2.5 3 1
6 2 CC 1.2.6 3 1
7 3 DD 1.3.7 3 1
8 3 UU 1.3.8 3 1
9 4 GG 1.4.9 3 1
10 4 LL 1.4.10 3 1
11 NULL KK 11 1 11
12 11 VV 11.12 2 11
Actual Tree structure
AA
BB
ZZ
HH
RR
CC
DD
UU
GG
LL
KK
VV
Expected ASCENDING ORDER OF TABLE
ID PANTID NAME FULLPATH LEVEL
____________________________________________
1 NULL AA 1 1
2 1 BB 1.2 2
6 2 CC 1.2.6 3
5 2 RR 1.2.5 3
4 1 HH 1.4 2
9 4 GG 1.9.4 3
10 4 LL 1.4.10 3
3 1 ZZ 1.3 2
7 3 DD 1.3.7 3
8 3 UU 1.3.8 3
11 NULL KK 11 1
12 11 VV 11.12 2
Expected ASCENDING TREE STRUCTURE
AA
BB
CC
RR
HH
GG
LL
ZZ
DD
UU
KK
VV
Expected DESCENDING ORDER OF TABLE
ID PARENTID NAME FULLPATH LEVEL
________________________________________________
11 NULL KK 11 1
12 11 VV 11.12 2
1 NULL AA 1 1
3 1 ZZ 1.3 2
7 3 DD 1.3.7 3
8 3 UU 1.3.8 3
4 1 HH 1.4 2
9 4 GG 1.9.4 3
10 4 LL 1.4.10 3
2 1 BB 1.2 2
6 2 CC 1.2.6 3
5 2 RR 1.2.5 3
Expected DESCENDING TREE STRUCTURE
KK
VV
AA
ZZ
UU
DD
BB
RR
CC
HH
LL
GG
Is FULLPATH
and actual field? You could use some clever string manipulation to convert it to a string that sorts exactly like you want (for example replacing all integers with a 6,7,8, however many you expect to need zero padded version). For example if you know you will never reach 1 million IDs turn 1 to 00000001, 1.2 to 0000001.0000002 etc. That should sort exactly as you want.
However this will sort same level IDs by ID and not by Name. If that is part of your specification which you do not mention but your example seems to do so, it will not work.
The only other ways I can think of have to do with assumption of a reasonable max level of nesting. In that case you would break each level into its own sub-query or view and re-integrate as linked tables.
Recursive CTE is the tool you should use. Here is working example for you. Note that your FULLPATH, LEVEL, and ROOTID fields are redundant.
declare @emp table (id int,parentId int, name varchar(10))--your table
insert @emp values --test values
(1 , NULL , 'AA'),
(2, 1, 'BB'),
(3, 1, 'ZZ'),
(4, 1, 'HH'),
(5, 2 , 'RR'),
(6, 2, 'CC'),
(7, 3, 'DD'),
(8, 3, 'UU'),
(9, 4, 'GG'),
(10, 4, 'LL'),
(11, NULL , 'KK'),
(12, 11, 'VV')
;with emps as (
--anckor query
select id, parentid, name,
format(id,'00000') sort, --format is sql 2012+ feature
1 lvl, --calc levels
format(100000-id,'00000') descsort --trick for desc sort
from @emp where parentId is null
union all --must be ALL
--recursive query
select e.id, e.parentid, e.name, sort+format(e.id,'00000') sort, lvl+1,descsort+format(e.id,'00000')
from @emp e
inner join emps on e.parentId=emps.id
)
select * from emps
order by sort --or **by descsort** if you want "desc"
stuff('00000',5-len(cast(id as varchar)),1000,cast(id as varchar))
;with emps as (
select id, parentid, name,
cast(left(name,2)+stuff('00000',5-len(cast(id as varchar)),1000,cast(id as varchar)) as varchar(max)) sort, --2008
--format(id,'00000') sort,
1 lvl,
format(100000-id,'00000') descsort -- use sort field as example
from @emp where parentId is null
union all
select e.id, e.parentid, e.name,
sort+left(e.name,2)+stuff('00000',5-len(cast(e.id as varchar)),1000,cast(e.id as varchar)),
--sort+format(e.id,'00000') sort,
lvl+1,descsort+format(e.id,'00000')
from @emp e
inner join emps on e.parentId=emps.id
)
select * from emps
order by sort -- descsort
;with emps as (
select id, parentid, name,
cast(left(name,2)+stuff('00000',5-len(cast(id as varchar)),1000,cast(id as varchar)) as varchar(max)) sort, --2008
--format(id,'00000') sort, --2012
1 lvl,
cast(stuff('00000',6-len(cast((100000-id) as varchar)),1000,cast((100000-id) as varchar))+left(name,2) as varchar(max)) descsort --2008
--format(100000-id,'00000') descsort -- use sort field as example
from @emp where parentId is null
union all
select e.id, e.parentid, e.name,
sort+left(e.name,2)+stuff('00000',5-len(cast(e.id as varchar)),1000,cast(e.id as varchar)),
--sort+format(e.id,'00000') sort,
lvl+1,
descsort+stuff('00000',6-len(cast(100000-e.id as varchar)),1000,cast(100000-e.id as varchar))+left(e.name,2)
--format(e.id,'00000')
from @emp e
inner join emps on e.parentId=emps.id
)
select * from emps
order by --sort desc--
descsort
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.