感觉你没描述清楚:输出结果受State中记录的顺序的影响,而这个顺序你并没有规定,是按照IP值从小到大排列后的State么?
解决方案 »
- 为什么我的SQL 2005用Windows身份验证登陆的时候出现18456错误
- 【求助】【SQL Server 2008】未能找到名为 CustomerIDNumber 的列。
- 一个论坛代码中的数据库查询语句的问题
- 疑难问题,召唤高手,关于BCP
- 如何判断一个字符串中包含中文
- 求助:日志中显示:SQL Server 未能衍生 process_loginread 线程。数据库停止响应
- 最快速的合计字段的方法?????????????????
- 在批量创建存储过程时,用到了在其后定义的存储过程,怎么才能让系统不报错呢
- 请哪为大哥帮帮我 急
- 有关EXEC返回结果的问题
- sql中怎么把","分开查询?比如现在有用户id:24,25,26.我用任意一个登入都可以查到.
- 如何查询结存
insert into IP select '202.200.120.0' , 1 , 0
insert into IP select '202.200.120.4' , 1 , 0
insert into IP select '202.200.120.8 ' , 1 , 0
insert into IP select '202.200.120.12' , 1 , 1
insert into IP select '202.200.120.16' , 1 , 0
insert into IP select '202.200.120.20' , 1 , 0
insert into IP select '202.200.120.24' ,2 , 0
insert into IP select '202.200.120.28' ,2 , 0select *,0 as tag into #t from ip--开始按需求编号
declare @tag int
set @tag =0
update #t set tag=@tag, @tag=@tag+case when state=1 then 1 else 0 endselect min(ip) Ipbegin ,max(ip) ipend, AreaID from #t where state<>1 group by AreaID,tag drop table #t
drop table Ip/*Ipbegin ipend AreaID
-------------------- -------------------- -----------
202.200.120.0 202.200.120.8 1
202.200.120.16 202.200.120.20 1
202.200.120.24 202.200.120.28 2(所影响的行数为 3 行)
*/
@ip varchar(32)
)
returns varchar(32)
as
begin
declare @is_ip varchar(32),@flag int
set @is_ip = @ip
set @flag = 0
while @flag = 0
begin
declare @ip_p varchar(32),@State int
select top 1 @ip_p = ip,@State = State from yourtable where left(ip,11) = left(@is_ip,11) and cast(replace(ip,'.','') as int) < cast(replace(@is_ip,'.','') as int) order by ip desc
if @ip_p is null or @State = 0 set @flag = 1
else set @is_ip = @ip_p
end
return(@is_ip)
endCREATE function f_GetEIP(
@ip varchar(32)
)
returns varchar(32)
as
begin
declare @is_ip varchar(32),@flag int
set @is_ip = @ip
set @flag = 0
while @flag = 0
begin
declare @ip_p varchar(32),@State int
select top 1 @ip_p = ip,@State = State from yourtable where left(ip,11) = left(@is_ip,11) and cast(replace(ip,'.','') as int) > cast(replace(@is_ip,'.','') as int) order by ip Asc
if @ip_p is null or @State = 0 set @flag = 1
else set @is_ip = @ip_p
end
return(@is_ip)
endselect distinct dbo.f_GetPIP(ip) Ipbegin,dbo.f_GetEIP(ip) Ipend,AreaId from yourtable
@ip varchar(32)
)
returns varchar(32)
as
begin
declare @is_ip varchar(32),@flag int
set @is_ip = @ip
set @flag = 0
while @flag = 0
begin
declare @ip_p varchar(32),@State int
select top 1 @ip_p = ip,@State = State from yourtable where left(ip,11) = left(@is_ip,11) and cast(replace(ip,'.','') as int) < cast(replace(@is_ip,'.','') as int) order by ip desc
if @ip_p is null or @State = 0 set @flag = 1
else set @is_ip = @ip_p
end
return(@is_ip)
endCREATE function f_GetEIP(
@ip varchar(32)
)
returns varchar(32)
as
begin
declare @is_ip varchar(32),@flag int
set @is_ip = @ip
set @flag = 0
while @flag = 0
begin
declare @ip_p varchar(32),@State int
select top 1 @ip_p = ip,@State = State from yourtable where left(ip,11) = left(@is_ip,11) and cast(replace(ip,'.','') as int) > cast(replace(@is_ip,'.','') as int) order by ip Asc
if @ip_p is null or @State = 0 set @flag = 1
else set @is_ip = @ip_p
end
return(@is_ip)
endselect distinct dbo.f_GetPIP(ip) Ipbegin,dbo.f_GetEIP(ip) Ipend,AreaId from yourtable
where state = 0
create table IP (ip char(15),AreaID int,State int)
insert into IP select '202.200.120.0' ,1,0
insert into IP select '202.200.120.4' ,1,0
insert into IP select '202.200.120.8 ' ,1,0
insert into IP select '202.200.120.12' ,1,1
insert into IP select '202.200.120.16' ,1,0
insert into IP select '202.200.120.20' ,1,0
insert into IP select '202.200.120.24' ,2,0
insert into IP select '202.200.120.28' ,2,0
GO--创建一个IP格式化的函数
create function dbo.f_formatip(@ip varchar(15))
returns varchar(15)
as
begin
declare @re varchar(16)
set @re=''
select @re=@re+right('00'
+substring(@ip,id,charindex('.',@ip+'.',id)-id)
,3)+'.'
from(
select id=a.id+b.id+1
from(
select id=0 union all select 1
union all select 2 union all select 3
)a,(
select id=0 union all select 4
union all select 8 union all select 12
)b
)a where substring('.'+@ip,id,1)='.'
return(left(@re,15))
end
go--处理
select *,0 as tag into #t from ip order by AreaID,dbo.f_formatip(ip)--开始按需求编号
declare @tag int
set @tag =0
update #t set tag=@tag, @tag=@tag+case when state=1 then 1 else 0 end
select min(ip) Ipbegin ,max(ip) ipend, AreaID from #t where state<>1 group by AreaID,tag
drop table #tGO
drop table IP
drop function f_formatip/*--结果Ipbegin ipend AreaID
--------------- --------------- -----------
202.200.120.0 202.200.120.0 1
202.200.120.16 202.200.120.8 1
202.200.120.24 202.200.120.28 2(所影响的行数为 3 行)
--*/
Ipbegin ipend AreaID
--------------- --------------- -----------
202.200.120.0 202.200.120.8 1
202.200.120.16 202.200.120.20 1
202.200.120.24 202.200.120.28 2
并且Ipbegin 应该小于ipend的
先按IP排序,根据state判断
楼主的2表分别设为table1,table2
代码如下:
declare @ip,@Areaid,@state,@beginip,@endip
set @beginip=''
declare me cursor for
select IP,AreaID,State from table1 order by IP
for readonlyopen me
fetch next from me into @ip,@Areaid,@state
while @@fetch_stat=0
begin
if @beginip='' and @state=0
begin
set @beginip=@ip
end
if @state=1
begin
insert into table2(Ipbegin,Ipend,areaid)values(@beginip,@endip,@Areaid)
end
set @endip=@ip
fetch next from me into @ip,@Areaid,@state
end
insert into table2(Ipbegin,Ipend,areaid)values(@beginip,@endip,@Areaid)GO
create table IP (ip char(20),AreaID int, State int)
insert into IP select '61.243.97.80' ,67 ,0
insert into IP select '61.243.97.84' ,67 ,0
insert into IP select '61.243.97.88' ,67 ,0
insert into IP select '61.243.97.92' ,68 ,0
insert into IP select '61.243.97.96' ,68 ,0
insert into IP select '61.243.97.100' ,68 ,1
insert into IP select '61.243.97.104' ,68 ,0
insert into IP select '61.243.97.108' ,68 ,0
insert into IP select '61.243.97.112' ,67 ,0
insert into IP select '61.243.97.116' ,67 ,0
insert into IP select '61.243.97.120' ,67 ,0
insert into IP select '61.243.97.124' ,67 ,1
insert into IP select '61.243.97.128' ,67 ,1select *,0 as tag into #t from ipselect * from #t--开始按需求编号
declare @tag int
declare @tag1 int
set @tag =0
set @tag1=0
update #t set tag=@tag, @tag=@tag+case when state=1 or AreaID<>@tag1 then 1 else 0 end, @tag1=AreaID
select min(ip) Ipbegin ,max(ip) ipend, AreaID from #t where state<>1 group by AreaID,tag drop table #t
drop table Ip--看看行不行
/*
Ipbegin ipend AreaID
-------------------- -------------------- -----------
61.243.97.80 61.243.97.88 67
61.243.97.92 61.243.97.96 68
61.243.97.104 61.243.97.108 68
61.243.97.112 61.243.97.120 67(所影响的行数为 4 行)
*/
还是不行
这样的数据可以,但是为什么我一用到数据量大的时候就不行了呢
有这样的分段:
Ipbegin ipend AreaID
-------------------- -------------------- -----------
61.243.97.0 61.243.97.24 67
61.243.97.44 61.243.97.88 67
61.243.97.112 61.243.97.116 67
61.243.97.136 61.243.97.252 68
61.243.111.228 61.243.111.240 68
其中61.243.97.44 61.243.97.88 这一段就不显示,直接就是 61.243.97.0 -61.243.97.116
怎么回事嘛,都快崩快了
关键在于分段的条件
我认为
State 遇见1 时要分段 或者AreaID 只要值发生变化就分段所以关键的一句话我写成这样
@tag=@tag+case when state=1 or AreaID<>@tag1 then 1 else 0 endwhen state=1 or AreaID<>@tag1 //条件
这只是我的理解,不知对不对
我不建议用游标效率不高
你的理解没错,就是这样的,但是最后执行
select min(ip) Ipbegin ,max(ip) ipend, AreaID from #t where state<>1 group by AreaID,tag
的时候出来的结果就不是我想要的了
你的错误在于不转换的时候,由于ip地址不是标准的格式,按你的比较:
5.1.1.1 就大于 205.1.1.1
这显然不对吧?我当时也没细想,犯了同样的错误,因为最终出结果是通过max与min的,所以应该还要改一下:select *,0 as tag,id=identity(int) into #t from ip order by AreaID,dbo.f_formatip(ip)
--开始按需求编号
declare @tag int
declare @tag1 int
set @tag =0
set @tag1=0
update #t set tag=@tag, @tag=@tag+case when state=1 or AreaID<>@tag1 then 1 else 0 end, @tag1=AreaID
--select min(ip) Ipbegin ,max(ip) ipend, AreaID from #t where state<>1 group by AreaID,tag
select Ipbegin=a.ip,ipend=b.ip,a.AreaID
from #t a,#t b,(
select id1=min(id),id2=max(id) from #t where state<>1 group by AreaID,tag )c
where a.id=c.id1 and b.id=c.id2drop table #t