论坛首页 综合技术论坛

一个捆扰我好几天sql分组排(树形结构查询+排序)

浏览 15715 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-06-19  
junjie314 写道
你这个函数真的写的不错  但是 还是有问题..你下看
id     fatherId menuPath  number
5 1 /5 23
7 5 /5/7 8
6 5 /5/6 9
8 6 /5/6/8 111
9 7 /5/7/9 222
2 1 /2 38
4 2 /2/4 4
3 2 /2/3 5

有多于三层子节点的话 排序就有问题 /5/7/9这个子节点应该排在他的父节点/5/7下面 现在却在/5/6/8下面了

这个问题好处理
    WHILE(@treeLevel<9) --此处9为目录层次数,经测试bigInt可以支持9级目录,再多目录层次就会出现益出   
    BEGIN   
        SET @weightLevel=@weightLevel*100  
        SET @treeLevel=@treeLevel+1  
    END   

你只需要缩小那个9(@treeLevel<9),比如设为6,这样可以支持6层菜单,增加那个100(@weightLevel=@weightLevel*100 )为1000就可以了,这样可以支持number最大为1000

具体数值根据你的需要设置
0 请登录后投票
   发表时间:2007-06-20  
如果ID小与32这个确实可以..但是如果ID大于32又有那个错了...实际运用中ID不可能小于32的吧....你可以试下哦..如果这个解决那就完美了..虽然只能支持到9层,不过应该也够了 嘿嘿
0 请登录后投票
   发表时间:2007-06-20  
junjie314 写道
如果ID小与32这个确实可以..但是如果ID大于32又有那个错了...实际运用中ID不可能小于32的吧....你可以试下哦..如果这个解决那就完美了..虽然只能支持到9层,不过应该也够了 嘿嘿

ID小与32是从哪里来的数值?
这种方法和ID的取值完全没有关系,就算ID大于1万,100万都没关系

这种方法的唯一限制是层数和number取值,因为太大了在计算的时候就超出了bigint的范围而溢出,不过六层/1000个节点在一般情况下应该已经足够了,再大的话适当调整一下也可以支持
0 请登录后投票
   发表时间:2007-07-17  
如果是用oracle, 看看这个会不会有帮助
http://www.adp-gmbh.ch/ora/sql/connect_by.html
0 请登录后投票
   发表时间:2007-07-17  
如果是sql server
看看这个
http://vyaskn.tripod.com/hierarchies_in_sql_server_databases.htm
0 请登录后投票
   发表时间:2007-07-20  
oracle 的话试试:

select t.id,t.fatherid,t.menupath,t.number
from table1 t
connect by prior t.id=t.fatherid
start with t.child_key_num=1
order by number asc;
0 请登录后投票
   发表时间:2007-07-20  
加了一个字段sortOrder,由上级的sortOrder + (本级number生成的等长字符串
需要触发器维护sortOrder字段
id    fatherID     menuPath    number      sortOrder
1	   NULL	      /1            1	     .0000000001
112	   1	      /112	        23	     .0000000001.0000000023
114	   112	      /112/114	    1	     .0000000001.0000000023.0000000001
116	   114	      /112/114/116	8	     .0000000001.0000000023.0000000001.0000000008
115	   114	      /112/114/115	9	     .0000000001.0000000023.0000000001.0000000009
113	   112	      /112/113	    2	     .0000000001.0000000023.0000000002
107	   1	      /107	        38	     .0000000001.0000000038
109	   107	      /107/109	    1	     .0000000001.0000000038.0000000001
111	   109	      /107/109/111  4	     .0000000001.0000000038.0000000001.0000000004
110	   109	      /107/109/110	5	     .0000000001.0000000038.0000000001.0000000005
108	   107	      /107/108	    2 	     .0000000001.0000000038.0000000002
0 请登录后投票
   发表时间:2007-07-20  
Sql Server 2000还是2005? 2005对于递归查询有新的语法。如果是sqlserver 2000可以自己用temp table模拟递归来避免层次过深的问题。
0 请登录后投票
   发表时间:2007-07-23  
id           fatherId             menuPath                 number    number_lev
107             1                   /107                     38      38
108            107                  /107/108                  2      38/2
109            107                  /107/109                  1      38/1
110            109                  /107/109/110              5      38/1/5
111            109                 /107/109/111               4      38/1/4
112             1                  /112                      23      23
113            112                 /112/113                   2      23/2
114            112                 /112/114                   1      23/1
115            114                 /112/114/115               9      23/1/9
116            114                 /112/114/116               8      23/1/8



order by number_lev ok?
0 请登录后投票
   发表时间:2007-07-26  
如果你用oracle好办得很,一个SQL搞定,主要思路是通过connect by 语句先解决层级查询问题,然后套大的子查询,采用oracle分组函数语句,进行分组,组内排序用partition ** order by **语法,具体我就不写了,查查这两种语法的用法就知道了。
0 请登录后投票
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics