最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了。

所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路。

 

1、sql2008 树形结构分组

http://bbs.csdn.net/topics/390634930

ID DeprtID DeprtName 
1   0        1        
2   1        2
3   1        3
4   2        4
5   3        5
6   4        6
7   5        7
分组后效果
ID DeprtID DeprtName 
1   0        1        
2   1        2
4   2        4
6   4        6
3   1        3
5   3        5
7   5        7

 

我的解法:

--drop table tb  create table tb(ID int, DeprtID int, DeprtName varchar(10))  insert into tb select 1,   0,        '1'         union all select 2 ,  1 ,       '2' union all select 3 ,  1 ,       '3' union all select 4 ,  2 ,       '4' union all select 5 ,  3 ,       '5' union all select 6 ,  4 ,       '6' union all select 7 ,  5,        '7' go   ;with t as ( select id,DeprtID,DeprtName,1 as level,        cast(right('000'+cast(id as varchar),3) as varchar(max)) as sort from tb where DeprtID =0  union all  select tb.id,tb.DeprtID,tb.DeprtName,level + 1 ,        cast(sort+right('000'+cast(tb.id as varchar),3) as varchar(max)) from t inner join tb          on t.id = tb.DeprtID )  select id,deprtid,deprtname from t order by sort /* id	deprtid	deprtname 1	0	    1 2	1	    2 4	2	    4 6	4	    6 3	1	    3 5	3	    5 7	5	    7 */

这里还有个例子,就是递归查询后,按照树形来排序:

drop table tb  create table tb ( id int, pid int, name varchar(20) )  insert into tb select 1,null,'x'  union all select 2,1,'a' union all select 3,1,'b' union all select 4,2,'aa' union all select 5,3,'bb' go   ;with t as ( select id,pid,name,1 as level,        cast(right('000'+cast(id as varchar),3) as varchar(max)) as sort from tb where pid is null  union all  select tb.id,tb.pid,tb.name,level + 1 ,        cast(sort+right('000'+cast(tb.id as varchar),3) as varchar(max)) from t inner join tb          on t.id = tb.pid )  select * from t order by sort /* id	pid	name	level	sort 1	NULL	x	1	001 2	1	a	2	001002 4	2	aa	3	001002004 3	1	b	2	001003 5	3	bb	3	001003005 */

 2、MS-SQL取连续日期问题  

http://bbs.csdn.net/topics/390635235?page=1#post-395995697

我现在需要得出表A中所有FBeginDate和FEndDate字段间的日期

下面是我的解法,使用了递归查询:

drop table tb  create table tb(FBeginDate datetime,FEndDate datetime)  insert into tb select '2010-10-01','2010-10-01' union all select '2010-10-01','2010-10-07' union all select '2011-01-30','2011-02-12'   ;with t as ( select 1 as number union all select number + 1 from t where t.number < 100 )  select tb.FBeginDate,        tb.FEndDate,        dateadd(day,t.number-1,FBeginDate) as '两个日期之间的天' from tb inner join t         on datediff(day,FBeginDate,FEndDate) +1 >= t.number order by tb.FBeginDate,          '两个日期之间的天'           /* FBeginDate	            FEndDate	            两个日期之间的天 2010-10-01 00:00:00.000	2010-10-01 00:00:00.000	2010-10-01 00:00:00.000 2010-10-01 00:00:00.000	2010-10-07 00:00:00.000	2010-10-01 00:00:00.000 2010-10-01 00:00:00.000	2010-10-07 00:00:00.000	2010-10-02 00:00:00.000 2010-10-01 00:00:00.000	2010-10-07 00:00:00.000	2010-10-03 00:00:00.000 2010-10-01 00:00:00.000	2010-10-07 00:00:00.000	2010-10-04 00:00:00.000 2010-10-01 00:00:00.000	2010-10-07 00:00:00.000	2010-10-05 00:00:00.000 2010-10-01 00:00:00.000	2010-10-07 00:00:00.000	2010-10-06 00:00:00.000 2010-10-01 00:00:00.000	2010-10-07 00:00:00.000	2010-10-07 00:00:00.000 2011-01-30 00:00:00.000	2011-02-12 00:00:00.000	2011-01-30 00:00:00.000 2011-01-30 00:00:00.000	2011-02-12 00:00:00.000	2011-01-31 00:00:00.000 2011-01-30 00:00:00.000	2011-02-12 00:00:00.000	2011-02-01 00:00:00.000 2011-01-30 00:00:00.000	2011-02-12 00:00:00.000	2011-02-02 00:00:00.000 2011-01-30 00:00:00.000	2011-02-12 00:00:00.000	2011-02-03 00:00:00.000 2011-01-30 00:00:00.000	2011-02-12 00:00:00.000	2011-02-04 00:00:00.000 2011-01-30 00:00:00.000	2011-02-12 00:00:00.000	2011-02-05 00:00:00.000 2011-01-30 00:00:00.000	2011-02-12 00:00:00.000	2011-02-06 00:00:00.000 2011-01-30 00:00:00.000	2011-02-12 00:00:00.000	2011-02-07 00:00:00.000 2011-01-30 00:00:00.000	2011-02-12 00:00:00.000	2011-02-08 00:00:00.000 2011-01-30 00:00:00.000	2011-02-12 00:00:00.000	2011-02-09 00:00:00.000 2011-01-30 00:00:00.000	2011-02-12 00:00:00.000	2011-02-10 00:00:00.000 2011-01-30 00:00:00.000	2011-02-12 00:00:00.000	2011-02-11 00:00:00.000 2011-01-30 00:00:00.000	2011-02-12 00:00:00.000	2011-02-12 00:00:00.000 */

3、求一个获取连续值的方法。

http://bbs.csdn.net/topics/390620211

这个用spt_values也可以。

如果是SQL Server 2005及以后的版本,可以通过递归来实现,非常简单。

我的解法:

;with r as ( select 1 as number   --第一个数  union all  select number + 1 from r where r.number < 10 --最后一个数 )  select * from r --option(maxrecursion 1000) /* number 1 2 3 4 5 6 7 8 9 10 */