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