I'm using the nested set model that'll later be used to build a sitemap for my web site. This is my table structure.
create table departments (
id int identity(0, 1) primary key
, lft int
, rgt int
, name nvarchar(60)
);
insert into departments (lft, rgt, name) values (1, 10, 'departments');
insert into departments (lft, rgt, name) values (2, 3, 'd');
insert into departments (lft, rgt, name) values (4, 9, 'a');
insert into departments (lft, rgt, name) values (5, 6, 'b');
insert into departments (lft, rgt, name) values (7, 8, 'c');
How can I sort by depth as well as name? I can do
select
replicate('----', count(parent.name) - 1) + ' ' + node.name
, count(parent.name) - 1 as depth
, node.lft
from
departments node
, departments parent
where
node.lft between parent.lft and parent.rgt
group by
node.name, node.lft
order by
depth asc, node.name asc;
However, that does not match children with their parent for some reason.
department lft rgt
---------------------------
departments 0 1
---- a 1 4
---- d 1 2
-------- b 2 5
-------- c 2 7
As you can see, department 'd' has department 'a's children!
Thank you.
The below will work with your example, although if a name contains the "-" character then it might break down. It might serve as a starting point though. This uses CTEs, which are specific to SQL Server I believe. If I think of a more generic ANSI SQL method, I'll post that as well.
;WITH Tree_Path AS (
SELECT
lft,
rgt,
name,
CAST(name + '-' AS VARCHAR(MAX)) AS tree_path,
1 AS depth
FROM
dbo.departments
WHERE
lft = 1
UNION ALL
SELECT
c.lft,
c.rgt,
c.name,
CAST(tp.tree_path + c.name + '-' AS VARCHAR(MAX)),
tp.depth + 1
FROM
Tree_Path tp
INNER JOIN dbo.departments AS c ON
c.lft > tp.lft AND
c.lft < tp.rgt AND
NOT EXISTS (SELECT * FROM dbo.departments d WHERE d.lft < c.lft AND d.rgt > c.lft AND d.lft > tp.lft AND d.lft < tp.rgt))
SELECT
REPLICATE('----', depth - 1) + name,
depth - 1,
lft
FROM
Tree_Path
ORDER BY
tree_path,
name
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With