没多少技术含量,在简单的系统里应用问题不大;

解决的问题是:

1.树结构数据的表设计;

2.对任意一个节点,找到他所有的上级节点

3.对任意一个节点,找到他所有的下级节点

这里的部分SQL是同事给的,具体出处不详;废话不多说,直接看例子吧;

1. 表设计,以比较常见的组织机构表为例,典型的树结构

create table Orgnization (
ID int not null,
Name nvarchar(50) not null,
Description nvarchar(300) null,
Leader nvarchar(50) null,
Status int null,
Parent int not null,
Path varchar(100) not null,
constraint PK_ORGNIZATION primary key (ID)
)

其中,Parent表示上级机构的ID,没有上级机构的话,就填0;

需要关注的是Path字段,由所有上级节点ID拼成的字符串,以逗号分隔,如: 0,1,4  , 4是父,1是爷,0是祖宗,依次类推

2.为方便测试,插入一些数据

INSERT INTO Orgnization([ID], [Name], [Description], [Leader], [Status], [Parent], [Path])  VALUES(1, 'XXX集团', null, null, null, 0, '');
INSERT INTO Orgnization([ID], [Name], [Description], [Leader], [Status], [Parent], [Path]) VALUES(2, '111事业部', null, null, null, 1, '0,1');
INSERT INTO Orgnization([ID], [Name], [Description], [Leader], [Status], [Parent], [Path]) VALUES(3, '222事业部', null, null, null, 1, '0,1');
INSERT INTO Orgnization([ID], [Name], [Description], [Leader], [Status], [Parent], [Path]) VALUES(4, '333事业部', null, null, null, 1, '0,1');
INSERT INTO Orgnization([ID], [Name], [Description], [Leader], [Status], [Parent], [Path]) VALUES(5, 'xxx部', null, null, null, 2, '0,1,2');
INSERT INTO Orgnization([ID], [Name], [Description], [Leader], [Status], [Parent], [Path]) VALUES(6, 'xxx2部', null, null, null, 2, '0,1,2');
INSERT INTO Orgnization([ID], [Name], [Description], [Leader], [Status], [Parent], [Path]) VALUES(7, 'XXX3部', null, null, null, 2, '0,1,2');
INSERT INTO Orgnization([ID], [Name], [Description], [Leader], [Status], [Parent], [Path]) VALUES(8, 'yyy部', null, null, null, 3, '0,1,3');
INSERT INTO Orgnization([ID], [Name], [Description], [Leader], [Status], [Parent], [Path]) VALUES(9, 'zzz部', null, null, null, 4, '0,1,4');
INSERT INTO Orgnization([ID], [Name], [Description], [Leader], [Status], [Parent], [Path]) VALUES(10, 'aaa组', null, null, null, 5, '0,1,2,5');
INSERT INTO Orgnization([ID], [Name], [Description], [Leader], [Status], [Parent], [Path]) VALUES(11, 'aaa2组', null, null, null, 5, '0,1,2,5');
INSERT INTO Orgnization([ID], [Name], [Description], [Leader], [Status], [Parent], [Path]) VALUES(12, 'aaa3组', null, null, null, 10, '0,1,2,5,10');
INSERT INTO Orgnization([ID], [Name], [Description], [Leader], [Status], [Parent], [Path]) VALUES(13, 'bbb组', null, null, null, 9, '0,1,4,9');

3. 找到所有上级节点

;with f as
(
select ID, Name,Parent,Path from Orgnization where [ID]= ''
union all
select a.ID,a.Name, a.Parent, a.Path from Orgnization a join f b on a.[ID]=b.[Parent]
)
select * from f order by Path asc

4.找到所有下级节点

这个相对复杂一点,这里采用的方式通过创建和调用SQL函数解决

4.1 创建一个字符串拆分split函数,用于解析类似0,1,4这种csv格式

/****** Object:  UserDefinedFunction [dbo].[m_split]    Script Date:  ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
create function [dbo].[m_split](@c varchar(2000),@split varchar(2))
returns @t table(col varchar(200))
as
begin
while(charindex(@split,@c) <>0)
begin
insert @t(col) values (substring(@c,1,charindex(@split,@c)-1))
set @c = stuff(@c,1,charindex(@split,@c),'')
-- SET @c = substring(@c,charindex(' ',@c)+1,len(@c))
end
insert @t(col) values (@c)
return
end
GO

4.2 创建一个用于在Path中匹配节点ID的函数

/****** Object:  UserDefinedFunction [dbo].[GetState]     ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
create function [dbo].[GetState](@s1 varchar(2000),@s2 varchar(2000))
returns int
as
begin
declare @i int
declare @j int
declare @k int
select @i=count(a.col) from dbo.m_split(@s1,',') a
right join (
select * from dbo.m_split(@s2,',')) b
on
a.col=b.col
where a.col is not null select @j=count(col) from dbo.m_split(@s1,',')
where col is not null if(@i=@j)
set @k=0
else
set @k=1
return @k
end GO

4.3 执行查询语句

select * from dbo.orgnization where dbo.GetState('', Path) = ''

SQL Server 处理树结构数据的一个示例的更多相关文章

  1. sql server存储过程返回数据只有一个字符

    SqlParameter[] param = { new SqlParameter("@shopId",shopId), new SqlParameter("@newSh ...

  2. 一个有趣的SQL Server 层级汇总数据问题

        看SQL Server大V宋大侠的博客文章,发现了一个有趣的sql server层级汇总数据问题.          具体的问题如下:     parent_id emp_id emp_nam ...

  3. Sql Server系列:数据表操作

    表是用来存储数据和操作数据的逻辑结构,用来组织和存储数据,关系数据库中的所有数据都表现为表的形式,数据表由行和列组成.SQL Server中的数据表分为临时表和永久表,临时表存储在tempdb系统数据 ...

  4. SQL Server内幕之数据页

    数据页是包含已添加到数据库表中的用户数据的结构. 如前所述, 数据页有三种, 每个都以不同的格式存储数据. SQL server 有行内数据页.行溢出数据页和 LOB 数据页. 与 SQL serve ...

  5. SQL Server 2005 系统数据介绍:dm_exec_connections

    原文:SQL Server 2005 系统数据介绍:dm_exec_connections 转载:http://msdn.microsoft.com/zh-cn/library/ms181509(SQ ...

  6. Expression构建DataTable to Entity 映射委托 sqlserver 数据库里面金额类型为什么不建议用float,实例告诉你为什么不能。 sql server 多行数据合并成一列 C# 字符串大写转小写,小写转大写,数字保留,其他除外 从0开始用U盘制作启动盘装Windows10系统(联想R720笔记本)并永久激活方法 纯CSS打造淘宝导航菜单栏 C# Winform

    Expression构建DataTable to Entity 映射委托   1 namespace Echofool.Utility.Common { 2 using System; 3 using ...

  7. Python 学习 第17篇:从SQL Server数据库读写数据

    在Python语言中,从SQL Server数据库读写数据,通常情况下,都是使用sqlalchemy 包和 pymssql 包的组合,这是因为大多数数据处理程序都需要用到DataFrame对象,它内置 ...

  8. sql server 随机读取数据

    --sql server 随机读取数据 * FROM [tablename] ORDER BY NEWID() pk from [tablename] ORDER BY NEWID()) --这两个方 ...

  9. sql server 与oracle数据互导的一种思路--sql server链接服务器

    思路:通过在sql server数据库中添加链接服务器,可以远程查询oracle数据库的表环境准备,安装sql server数据库,并安装好oracle驱动,在配置好tnsname文件中配置好orac ...

随机推荐

  1. js中Array对象方法详解

    操作方法:concat() slice() splice() concat()方法可以基于当前数组中的所有项创建一个新数组.具体来说,这个方法会创建当前数组一个副本,将接收到参数添加到副本的末尾,最后 ...

  2. RichEdit

    RichEdit 设置字符颜色 ; ; this->RichEdit1->SelAttributes->Color=clRed; 行间距字符间距 void __fastcall TF ...

  3. XidianOJ 1182 Chinese Paladin – Qi’s troubles

    题目描述 As we all know, Xiahou Jinxuan (Chinese Paladin 5 Prequel's protagonist) and Yue Jinzhao (Chine ...

  4. C/C++关键字 extern

    1.基本解释:extern 可置于变量或函数前面,表示变量或函数的定义在别的文件中,以提示编译器遇到此变量或函数时在其他模块中寻找定义. extern还有另外2个作用.第一:与“C”连用时,如 ext ...

  5. z-tree

    1 获取所有的节点集合 var nodes = treeObj.getNodes();//只获取根节点 var nodesAll = treeObj.transformToArray(nodes);/ ...

  6. CSS背景图拉伸自适应尺寸,全浏览器兼容

    突然有人问我这个问题,说网上CSS filter的方法在非IE浏览器下不奏效.思考之后,问题之外让我感慨万千啊,很多我们所谓的难题,都会随着时代的发展迎刃而解,或被新的问题所取代. 当CSS背景图片拉 ...

  7. socket编程相关的结构体和字节序转换、IP、PORT转换函数

    注意:结构体之间不能直接进行强制转换, 必须先转换成指针类型才可以进行结构体间的类型转换, 这里需要明确的定义就是什么才叫强制转换. 强制转换是将内存中一段代码以另一种不同类型的方式进行解读, 因此转 ...

  8. 通过反射向将EF的实体映射配置加入到实体模型中

    public AdminDbContext() : base("MemberDbContext") { //不使用代理创建导航属性,避免WCF序列化错误 Configuration ...

  9. X Window 设定介绍

    在 Unix Like 上面的图形用户接口 (GUI) 被称为 X 或 X11 X11 是一个『软件』而不是一个操作系统: X11 是利用网络架构来进行图形接口的执行与绘制: 最著名的 X 版本为 X ...

  10. 如何通过maven ,将本地jar 安装到仓库中去。

    场景: 现在很多公司,都有 maven 的私服 ,在maven项目中,基本上有两个仓库 ,一个是maven的公共仓库,一个是私服仓库: 有的时候,我们download 别人的代码的时候,pom文件中报 ...