/*--
第一层 - 1
第二层 - 2 3
第三层 - 4 5 6 7
第四层 - 8 9 10 11 12 13 14 15
将顺序的数据(1~N)依如下规则排列
1,排成塔形.
2,下一层所排数字是对上一层的两倍.(第一层为1个,第二层为2个,第三层4个,如此类推)
3,自上到下,自左到右紧密排列.
现在要找出每个号码下面号码的个数.
--邹建 2004.4--*/
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_id]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[f_id]
GO
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_id_num]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[f_id_num]
GO
--得到每个号码下面包含的号码
create function f_id(
@num int, --那个数下面的子
@max_num int --统计结束的数字
)returns @re table(id int identity(1,1),num int,level int)
as
begin
declare @level int,@left int,@i int,@j int
if @num>@max_num goto lb_re
select @level=0,@i=@num
while @i>1
select @level=@level+1,@i=@i/2
insert @re values(@num,@level+1)
select @left=(@num%power(2,@level))*2
,@level=@level+1
,@num=power(2,@level)
,@i=0,@j=2
while 1=1
begin
while @i<@j
begin
if (@left+@num+@i)>@max_num goto lb_re
insert @re values(@left+@num+@i,@level+1)
set @i=@i+1
end
select @level=@level+1
,@left=@left*2
,@num=@num*2
,@i=0,@j=@j*2
end
lb_re:
return
end
go
--得到每个号码下面包含的号码个数
create function f_id_num(
@num int, --那个数下面的子
@max_num int --统计结束的数字
)returns int
as
begin
declare @level int,@left int,@re int,@i int,@j int
set @re=0
if @num>@max_num goto lb_re
select @level=0,@i=@num
while @i>1
select @level=@level+1,@i=@i/2
select @left=(@num%power(2,@level))*2
,@level=@level+1
,@num=power(2,@level)
,@i=0,@j=2
while 1=1
begin
while @i<@j
begin
if (@left+@num+@i)>@max_num goto lb_re
select @re=@re+1,@i=@i+1
end
select @level=@level+1
,@left=@left*2
,@num=@num*2
,@i=0,@j=@j*2
end
lb_re:
return(@re)
end
go
--调用实现查询
select * from f_id(2,8)
select dbo.f_id_num(2,8)
go
/*--测试结果
id num level
----------- ----------- -----------
1 3 2
2 6 3
3 7 3
4 12 4
5 13 4
6 14 4
7 15 4
(所影响的行数为 7 行)
--*/
129.宝塔形数据的处理-案例
最新推荐文章于 2023-05-27 10:54:25 发布