zoukankan      html  css  js  c++  java
  • SqlServer自定义排序

      在实际项目中,有时会碰到数据库SQL的特殊排序需求,举几个例子,作为参考。

    1、自定义优先级

      一种常见的排序需求是指定某个字段取值的优先级,根据指定的优先级展示排序结果。比如如下表:

    Create TABLE Fruit (id INT IDENTITY(1, 1) ,Name VARCHAR(50));
    
    INSERT  INTO Fruit (Name) VALUES  ('Apple');
    INSERT  INTO Fruit (Name) VALUES  ('Watermelon');
    INSERT  INTO Fruit (Name) VALUES  ('Strawberry');
    INSERT  INTO Fruit (Name) VALUES  ('Banana');
    INSERT  INTO Fruit (Name) VALUES  ('Pear');
    

      如果按照Name字段排序,结果是

    Apple
    Banana
    Pear
    Strawberry
    Watermelon
    

      如果想把某个字段优先级提高,用如下方法:

    select name from fruit 
    order by case name 
    	when 'Strawberry' then 1
    	when 'Banana' then 2
    	when 'Apple' then 3 
    	else 4
    end
    

      指定了Strawberry、Banana、Apple三条记录的排序优先级,则这三个按照指定的结果排序,其他的都指定为4,排在后面。

    Strawberry
    Banana
    Apple
    Watermelon
    Pear
    

      如果不指定else 4这句呢,结果如下:

    Watermelon
    Pear
    Strawberry
    Banana
    Apple
    

      因为不指定就是NULL,在排序中,NULL的优先级最高,排在前面。

    2、多字段关联排序

      考虑如下需求:有一个机构表,需要按照深度优先排序,也就是一个机构的下级机构和下下级机构的优先级比同级机构高。

      表结构有三个字段:机构号、机构名称、上级机构号:

    branchnum	branchname	supbranchnum
    1		本部	        00000
    2		北京市分行    	00001
    3		天津市分行    	00001
    4		河北省分行    	00001
    5		山西省分行    	00001
    2001		北京中关村中心支行	00002
    2002		北京王府井支行  	00002
    2006		北京奥运村支行  	00002
    2010		北京东城支行   	00002
    2026		北京西城支行   	00002
    2044		北京崇文支行   	00002
    2061		北京宣武支行   	00002
    2077		北京朝阳支行   	00002
    2099		北京海淀支行   	00002
    2135		北京丰台支行   	00002
    2137		北京方庄中心支行 	00002
    2154		北京首都机场支行 	00002
    2160		北京通州支行   	00002
    2169		北京大兴支行   	00002
    2175		北京世纪财富中心支	00002
    2178		北京顺义支行   	00002
    2185		北京昌平支行   	00002
    2194		北京平谷支行   	00002
    2195		北京密云支行   	00002
    2198		北京怀柔支行   	00002
    2204		北京延庆支行   	00002
    2206		北京金融中心支行 	00002
    2209		北京中银大厦支行 	00002
    2210		北京石景山支行  	00002
    2211		北京商务区支行  	00002
    2227		北京使馆区支行  	00002
    2228		北京国际贸易中心支	00002
    2231		北京上地支行	00002
    2232		北京投资广场支行 	00002
    2233		北京雅宝路支行  	00002
    2354		天津大港支行   	00003
    2361		天津和平支行   	00003
    2382		天津河西支行   	00003
    2398		天津南开支行   	00003
    2412		天津红桥支行   	00003
    2423		天津河北支行   	00003
    2447		天津河东支行   	00003
    2463		天津津南支行   	00003
    2470		天津北辰支行   	00003
    2478		天津东丽支行   	00003
    2484		天津西青支行   	00003
    2492		天津武清支行   	00003
    2500		天津宝坻支行   	00003
    2504		天津汉沽支行   	00003
    2508		天津宁河支行   	00003
    2510		天津蓟县支行   	00003
    2519		天津静海支行   	00003
    2523		天津津钢支行   	00003
    2601		石家庄市机场路支行	00004
    2626		石家庄市中山支行 	00004
    2652		石家庄市裕东支行 	00004
    2678		石家庄市裕华支行 	00004
    3451		太原鼓楼支行   	00005
    3479		太原平阳支行   	00005
    3494		太原并州支行   	00005
    3506		太原漪汾支行   	00005
    

      可以写一个排序函数,对每一个机构计算它的排序值,排序值就等于上级机构号:

    Create FUNCTION fn_compare
    (
    	@Branchnum int
    )
    RETURNS int
    AS
    BEGIN
    	declare @returnVal int
    	select @returnVal=supBranchnum from Branch where Branchnum=@Branchnum
    	if(@returnVal=1)
    	Begin
    		set @returnVal=@Branchnum
    	End
    	return @returnVal
    END
    GO
    

      然后通过如下语句查询排序结构:

      select branchnum,branchname,supbranchnum from branch
      order by dbo.fn_compare(branchnum),branchnum
    

      因为fn_compare函数中,对一个机构和它下级机构返回的排序值(ReturnVal)相等,所以为了使上级机构号排在下级机构前面,需要使用第二个排序字段Branchnum。排序结果如下:

    branchnum	branchname	supbranchnum
    1		本部	      00000
    2		北京市分行    	 00001
    2001		北京中关村中心支行	 00002
    2002		北京王府井支行  	 00002
    2006		北京奥运村支行  	 00002
    2010		北京东城支行   	 00002
    2026		北京西城支行   	 00002
    2044		北京崇文支行   	 00002
    2061		北京宣武支行   	 00002
    2077		北京朝阳支行   	 00002
    2099		北京海淀支行   	 00002
    2135		北京丰台支行   	 00002
    2137		北京方庄中心支行 	 00002
    2154		北京首都机场支行 	 00002
    2160		北京通州支行   	 00002
    2169		北京大兴支行   	 00002
    2175		北京世纪财富中心支  00002
    2178		北京顺义支行   	 00002
    2185		北京昌平支行   	 00002
    2194		北京平谷支行   	 00002
    2195		北京密云支行   	 00002
    2198		北京怀柔支行   	 00002
    2204		北京延庆支行   	 00002
    2206		北京金融中心支行 	 00002
    2209		北京中银大厦支行 	 00002
    2210		北京石景山支行  	 00002
    2211		北京商务区支行  	 00002
    2227		北京使馆区支行  	 00002
    2228		北京国际贸易中心支  00002
    2231		北京上地支行	 00002
    2232		北京投资广场支行 	 00002
    2233		北京雅宝路支行  	 00002
    20170		北京房山支行   	 00002
    3		天津市分行    	 00001
    2354		天津大港支行   	 00003
    2361		天津和平支行   	 00003
    2382		天津河西支行   	 00003
    2398		天津南开支行   	 00003
    2412		天津红桥支行   	 00003
    2423		天津河北支行   	 00003
    2447		天津河东支行   	 00003
    2463		天津津南支行   	 00003
    2470		天津北辰支行   	 00003
    2478		天津东丽支行   	 00003
    2484		天津西青支行   	 00003
    2492		天津武清支行   	 00003
    2500		天津宝坻支行   	 00003
    2504		天津汉沽支行   	 00003
    2508		天津宁河支行   	 00003
    2510		天津蓟县支行   	 00003
    2519		天津静海支行   	 00003
    2523		天津津钢支行   	 00003
    4		河北省分行    	 00001
    2601		石家庄市机场路支行	 00004
    2626		石家庄市中山支行 	 00004
    2652		石家庄市裕东支行 	 00004
    2678		石家庄市裕华支行 	 00004
    5		山西省分行    	 00001
    3451		太原鼓楼支行   	 00005
    3479		太原平阳支行   	 00005
    3494		太原并州支行   	 00005
    3506		太原漪汾支行   	 00005
    

      

  • 相关阅读:
    Navicat 创建mysql存过、定时执行存过
    windows 系统 MySQL_5.6.21安装教程
    ldf和mdf文件怎么还原到sqlserver数据库
    免安装的tomcat转服务
    关掉IE提示“当前安全设置会使计算机有风险”
    U盘制作系统启动盘方法
    Tomcat窗口标题,中文乱码解决方法
    MyEclipse10安装SVN插件
    IE浏览器的卸载操作
    739. Daily Temperatures 每日温度
  • 原文地址:https://www.cnblogs.com/wangguanguo/p/8337715.html
Copyright © 2011-2022 走看看