zoukankan      html  css  js  c++  java
  • 树形结构部门的 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。

  • 相关阅读:
    mysql标准写法及其他常见问题
    java动态代理_aop2
    java动态代理_aop
    oracle11g exp导出问题:部分表导不出来
    决策树算法学习笔记
    阿里云九折优惠码
    标准差(Standard Deviation) 和 标准误差(Standard Error)
    Pipeline 与 xargs
    【Linux运维-集群技术进阶】Nginx+Keepalived+Tomcat搭建高可用/负载均衡/动静分离的Webserver集群
    求最大连续和——dp
  • 原文地址:https://www.cnblogs.com/myfjd/p/4293831.html
Copyright © 2011-2022 走看看