树形结构部门的 sqlserver 排序

树形结构部门的 sqlserver 排序

因为要实现部门排序功能,而且要考虑部门的层级,直接用 sql 排序是不行的,所以写个 sql function 来支持。 
首先部门表:company

CREATE TABLE company(
CompanyId           id         NOT NULL,
CompanyName         nvarchar(115)    NOT NULL
)

记录部门层级结构的表,如果部门没有上级部门则在这张表中不会有记录

CREATE TABLE company_report(
CompanyId     id    NOT NULL,
ReportToId    id    NOT NULL,
DisplayOrd    ord   CONSTRAINT [DF1_company_report] DEFAULT (1) NOT NULL
)

在 company_report 中 ReportToId 是指上级部门的 CompanyId 。 
像这种树形结构,在代码中一般都是用递归来遍历了,但是在 sql 中实现递归还是很麻烦的,还是写成循环简单点。 
定义 function :

go
if (exists (select * from sys.objects where name = ‘get_company_report_name_fn‘))
drop FUNCTION get_company_report_name_fn
go
CREATE FUNCTION get_company_report_name_fn (@i_vCompanyId id, @i_vCompanyName string2)
RETURNS string2
AS
BEGIN
   DECLARE @t_vResult string2;
   DECLARE @t_vReportToId id;

   SET @t_vResult = ‘‘;
   --父部门ID
   SET @t_vReportToId = 0;
   --拼接父部门Name
   SELECT @t_vResult = r.CompanyName + ‘_‘ + c.CompanyName,
   @t_vReportToId =  cr.ReportToId
   FROM company_report cr, company c, company r
   WHERE cr.CompanyId = c.CompanyId
     AND cr.ReportToId = r.CompanyId
      AND cr.CompanyId = @i_vCompanyId
   --while 父部门还存在父部门
   while (
      exists(select cr.ReportToId from company_report cr where cr.CompanyId = @t_vReportToId)
   )
   begin
        SELECT @t_vResult = r.CompanyName + ‘_‘+  @t_vResult,
         @t_vReportToId =  cr.ReportToId
         FROM company_report cr, company c, company r
         WHERE cr.CompanyId = c.CompanyId
           AND cr.ReportToId = r.CompanyId
           AND cr.CompanyId = @t_vReportToId
   end
   --已经是最顶层的部门了 返回原值
   if @t_vResult = ‘‘
   begin
      SET @t_vResult = @i_vCompanyName
   end

   return @t_vResult
END
GO

原理就是在子部门的 name 上加上父部门的 name 用 _ 符号连接,如果父部门还存在父部门则继续连接下去。 
在排序的时候这样调用:

select dbo.get_company_report_name_fn(companyId, companyName) from company order by dbo.get_company_report_name_fn(companyId, companyName)

结果:

ula-client01 LTD.
ula-client01 LTD._ula-client02
ula-client01 LTD._ula-client02_ula-client02-子
ula-client01 LTD._ula-client03
Sony
Sony_Hair
Sony_Hair_IBM

写完给 Leader 看看,他觉得我写复杂了,然后就随手改了下:

go
if (exists (select * from sys.objects where name = ‘get_company_report_name_fn‘))
drop FUNCTION get_company_report_name_fn
go
CREATE FUNCTION get_company_report_name_fn (@i_vCompanyId id, @i_vCompanyName string2)
RETURNS string2
AS
BEGIN
   DECLARE @t_vResult string2;
   DECLARE @t_vReportToId id;
   DECLARE @t_vReportToName string2;

   SET @t_vResult = @i_vCompanyName;
   SET @t_vReportToId = @i_vCompanyId;

   while (exists(select cr.ReportToId from company_report cr where cr.CompanyId = @t_vReportToId))
   begin
      SELECT @t_vReportToId = cr.ReportToId, @t_vReportToName = c.companyName
      FROM company_report cr, company c
      WHERE cr.ReportToId = c.CompanyId
      AND cr.CompanyId = @t_vReportToId;
     set @t_vResult = @t_vReportToName + ‘_‘ + @t_vResult;
   end

   return @t_vResult;
END
go

好吧,是简单了很多。主要是消除了重复的代码。 
END。

时间: 2024-10-12 03:47:50

树形结构部门的 sqlserver 排序的相关文章

YbSoftwareFactory 代码生成插件【十八】:树形结构下的查询排序的数据库设计

树形结构的排序在中国特色下十分普遍也非常重要,例如常说的五大班子,党委>人大>政府>政协>纪委,每个班子下还有部门,岗位,人员,最终排列的顺序通常需要按权力大小.重要性等进行排列,顺序排列不好可是重大的罪过,领导很生气,后果很严重.这种排序方式本质上就是典型的树形结构深度排序,但在数据库中很难直接通过SQL语句简单高效地进行处理,更不用说还要支持不同类型数据库了. 当前解决此类问题,主要有两种方法. 1. 排序码方式 原理:在每个树形节点上均设置一个排序码,排序码通常是一个字符串并

Java创建树形结构算法实例

在JavaWeb的相关开发中经常会涉及到多级菜单的展示,为了方便菜单的管理需要使用数据库进行支持,本例采用相关算法讲数据库中的条形记录进行相关组装和排序讲菜单组装成树形结构. 首先是需要的JavaBean 1 2 3 import java.io.Serializable; 4 import java.util.ArrayList; 5 import java.util.Collections; 6 import java.util.Comparator; 7 import java.util.

你认为扁平化模式好还是树形结构好?

我认为对于小公司来说,扁平化的模式更好一些.由于小公司的规模比较小,公司内的员工不多,所需要的管理层次不多.扁平化模式的决策层和操作层之间的中间管理层次少,这可以使企业能够快速地将决策权延至企业生产.营销的最前线,从而为提高企业效率.而且由于公司规模小,管理部门之间的信息资源的交流.相互调用不会太多,这样可以是决策者集中更多的精力在企业的市场对策和企业发展的战略问题上. 对于大公司来说,树形结构会更好一些.大公司的规模比较大,所要做的项目比较多,如果一个人负责多个项目会造成项目完成效率不高.在树

Delphi中根据分类数据生成树形结构的最优方法

一. 引言:    TreeView控件适合于表示具有多层次关系的数据.它以简洁的界面,表现形式清晰.形象,操作简单而深受用户喜爱.而且用它可以实现ListView.ListBox所无法实现的很多功能,因而受到广大程序员的青睐.    树形结构在Windows环境中被普遍应用,但在数据库开发中面对层次多.结构复杂的数据,如何快速构造树形目录并实现导航呢?    二. 实现关键技术:    在Delphi提供的控件中包含了TreeView控件,但树的具体形成还需要用户编写代码.即它的列表项要在程序

树形结构的数据库的存储

程序设计过程中,我们常常用树形结构来表征某些数据的关联关系,如企业上下级部门.栏目结构.商品分类等等,通常而言,这些树状结构需要借助于数据库完成持久化.理想中树形结构应该具备如下特征:数据存储冗余度小.直观性强:检索遍历过程简单高效:节点增删改查CRUD操作高效. 列举了一个食品族谱的例子进行讲解,通过类别.颜色和品种组织食品,树形结构图如下: 1,对树形结构最直观的分析莫过于节点之间的继承关系上,通过显示地描述某一节点的父节点,从而能够建立二维的关系表,则这种方案的Tree表结构通常设计为:{

java工程积累——树形结构的操作

最近一直被树形结构整的很头大,又是递归,又是循环,但是,好在我们在经历了千辛万苦后,终于弄出来了,其实就是组织机构的常规操作,有些是我们过度设计,有些是我们想错了,而对数的逻辑读取,我们就属于想错了的类型,今天拿出来和大家分享,主要是树形结构在数据库的读取问题! 原始: 在最开始,我们对树的查询,肯定是从最简单的select开始,我们现在回顾一下: 定义: 表名:tb_tree 字段:id(主键),title(标题),parentId(父节点id) 举例: 1.查找树中的所有顶级父节点(辈份最长

Extjs实现树形结构三连选

当项目中需要一个部门人员选择或者省市县地域连选时,就需要树形结构的连选. 再此,写了一个简单的树形结构三连选功能,模拟从后台读取数据和处理数据(欢迎大家交流指正). 代码如下: 循环创建三棵树,其中只有第一棵树有数据,并从后台读取. var root = new Array(); var tree = new Array(); var loader = new Ext.tree.TreeLoader({ dataUrl: 'datatree.aspx' }) for (var i = 0; i

【转】BBS树形结构的实现方法

网站上的树形回复是如何实现的. 有两种实现方法:1.用中值排序基数法实现树状结构. 2.用递归算法实现 1.----------------用中值排序基数法实现树状结构. 下面给出另一种使用“使用中值排序基数法”实现树状结构:一.主要思想:增加一个排序基数字段ordernum,回复同一根贴的贴子中插入贴子时,排序基数ordernum取两者的中值.    为了叙述的简洁,在此只讨论与树状结构有关的字段. 在表中增加三个冗余字段,rootid——用于记录根id,deep——用于记录回复的深度(为0时

WPF实现完美的树形结构和右键菜单(下)

上篇讲了TreeView的样式 这篇讲TreeView的数据绑定与邮件菜单的实现 看下图: 先来看看TreeView的数据绑定 <TreeView x:Name="TrvList" Grid.Row="1" Margin="4 8 0 0" VerticalAlignment="Stretch" ContextMenu="{DynamicResource ContractContextMenu}" I