按名称对嵌套集进行排序,同时保持深度完整性
我正在使用嵌套集模型,稍后将使用该模型为我的网站构建站点地图。这是我的表结构。
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');
如何按深度和名称排序?我可以做
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;
但是,由于某种原因,这与孩子和父母不匹配。
department lft rgt
---------------------------
departments 0 1
---- a 1 4
---- d 1 2
-------- b 2 5
-------- c 2 7
正如您所看到的,部门“d”有部门“a”的子级!
谢谢。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我想我终于想出了一个 ANSI SQL 解决方案。基本要点是,它计算父级与节点自己的父级之一具有较低值名称的行数,或者本身与节点处于同一级别并具有较低值名称的行数。如果需要,您需要对其进行细微调整才能添加缩进。另外,我不知道所有子查询在大型数据集上的性能如何:
如果您遇到任何中断的情况,请告诉我。
I think I finally came up with an ANSI SQL solution. The basic gist is that it counts the number of rows that either have parents with a lower valued name on the same level as one of the node's own parent or is itself on the same level as the node and has a lower valued name. You'll need to make a minor adjustment to it in order to add the indenting if you want it. Also, I don't know how performance on a large data set will be due to all of the subqueries:
Let me know if you come up with any situations where it breaks.
下面的内容将适用于您的示例,但如果名称包含“-”字符,则它可能会崩溃。不过,它可以作为一个起点。这使用了 CTE,我相信这是 SQL Server 特有的。如果我想到更通用的 ANSI SQL 方法,我也会发布它。
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.
问题中有一个不匹配的地方。查询返回:
node.name
、深度
和node.lft
——但结果表标记为:无论如何,该查询是返回部门级别的正确结果——在这种情况下,这显然不是您想要的深度含义。 a 和 d 都是顶级部门。
如果您想要子部门的数量,并且嵌套集得到正确维护,那么查询很简单:
There is a mismatch in the question. The query returns:
node.name
,depth
, andnode.lft
-- yet the results table is labeled with:Anyway, that query is returning the correct results for department level -- which is apparently not what you want depth to mean in this case. Both a and d are top-level departments.
If you want the number of sub-departments, and the nested-set is kept properly maintained, then the query is simply: