樹形結構部門的 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。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM