SQL高手请进!
有两个表 a(id,aa,bb),b(id,aa,bb)
//==============================
表a
id aa bb
--------------------------------
1 1001 2000
//==============================
表b
id aa bb
1 1003 1050
1 1100 1150
1 1151 1900
现根据ID进行关联,要得到b表在a表中不存在的区段,即结果如下:
id aa bb
1 1001 1002
1 1051 1099
1 1901 2000
问怎么用最佳的方法来实现?
问题点数:100、回复次数:18Top
1 楼hfayga(飞白)回复于 2002-12-24 16:26:51 得分 0
这个能用SQL实现吗?最多先筛出b表在a表中的位置,然后用SQL过程来分析表中数据,然后填入表中!Top
2 楼zjhnwlh(清嘴)回复于 2002-12-24 16:38:36 得分 0
有没有较好的分析方法,贴出来大家切磋切磋!Top
3 楼CrazyFor(冬眠的鼹鼠)回复于 2002-12-24 16:44:18 得分 0
select b.* from b where cast(id as varchar)+','+cast(aa as varchar)+','+cast(bb as varchar) not in (
select cast(id as varchar)+','+cast(aa as varchar)+','+cast(bb as varchar) from A
)Top
4 楼zjhnwlh(清嘴)回复于 2002-12-25 10:06:03 得分 0
CrazyFor(为谁倾狂) 不对!再看看Top
5 楼zjhnwlh(清嘴)回复于 2002-12-25 10:08:08 得分 0
结果是一个中间差Top
6 楼sky_blue(蓝天2007)回复于 2002-12-25 10:18:51 得分 0
表a中ID是否唯一?Top
7 楼zjhnwlh(清嘴)回复于 2002-12-25 10:24:09 得分 0
ID是唯一的Top
8 楼zjhnwlh(清嘴)回复于 2002-12-25 10:26:57 得分 0
其实这个问题时票据问题的一个典型例子。
如:A表 是领票据的连续编号1001---2000;
b表 就是票据核销的部分票据
下在就是要求得还有那些票据没有核销。Top
9 楼hillhx(曾经的曾经)回复于 2002-12-25 10:29:11 得分 0
我觉得用一句SQL是写不出来这个效果的Top
10 楼zjhnwlh(清嘴)回复于 2002-12-25 10:31:54 得分 0
不一定要一句SQL语句来实现这个功能
也可以用存贮过程等方法来实现Top
11 楼CrazyFor(冬眠的鼹鼠)回复于 2002-12-25 10:39:41 得分 0
select b.* from b where cast(id as varchar)+','+cast(aa as varchar)+','+cast(bb as varchar) not in (
select cast(id as varchar)+','+cast(aa as varchar)+','+cast(bb as varchar) from A
)
这句有什么问题,贴出来看看。Top
12 楼sky_blue(蓝天2007)回复于 2002-12-25 10:47:32 得分 30
分析:
如果有如下数据:
id aa bb
--------------------------------
1 1500 2000
//==============================
表b
id aa bb
1 1000 2050
则应该有两条结果数据:
1000 1500
2000 2050
所以查询比较复杂。
另外,表A和表B中是否确定BB大于AA?否则难度又要提高。呵呵
Top
13 楼zjhnwlh(清嘴)回复于 2002-12-25 10:55:05 得分 0
CrazyFor(为谁倾狂)你的查询结果不是一个中间差,而是B表的数据Top
14 楼sky_blue(蓝天2007)回复于 2002-12-25 10:57:51 得分 0
我的想法是先把上面的这种数据变成两条数据
id aa bb
--------------------------------
1 1500 2000
//==============================
表b
id aa bb
1 1000 2000
1 2000 2050
这样可能就好分析一点。
Top
15 楼XLYT(雨田)回复于 2002-12-25 11:24:32 得分 50
比较麻烦,但有点意思。
declare @intida smallint,@intaaa int,@intbba int
declare @intaab int,@intbbb int
declare @intaa int
if exists(select * from tempdb..sysobjects where name like '#tmptable%') drop table #tmptable
create table #tmptable (id smallint,aa int,bb int)
declare cursora cursor for select * from tablea order by id
open cursora
fetch next from cursora into @intida,@intaaa,@intbba
set @intaa=@intaaa
while @@fetch_status=0
begin
declare cursorb cursor for select aa,bb from tableb where id=@intida order by aa
open cursorb
fetch next from cursorb into @intaab,@intbbb
while @@fetch_status=0
begin
if @intaa<@intaab insert #tmptable values (@intida,@intaa,@intaab-1)
set @intaa=@intbbb+1
fetch next from cursorb into @intaab,@intbbb
end
insert #tmptable values (@intida,@intaa,@intbba)
close cursorb
fetch next from cursora into @intida,@intaaa,@intbba
end
close cursora
deallocate cursora
deallocate cursorb
select * from #tmptable
Top
16 楼zjhnwlh(清嘴)回复于 2002-12-25 12:44:32 得分 0
对于字符串的怎样来处理较为合适!Top
17 楼CrazyFor(冬眠的鼹鼠)回复于 2002-12-25 13:16:22 得分 20
1,建自定义函数:
CREATE FUNCTION GetMinValue (@inputId int,@startV int,@endV int)
RETURNS int AS
BEGIN
declare @rV int
select @rV=isnull((select top 1 ccc from (
select AA as CCC from b where id=@inputId and aa>@startV
union
select BB As CCC from b where id=@inputId and BB>@startV ) CC
order by cc.ccc),@EndV)
return @rv
END
-------------
declare @intida int,@intaaa int,@intbba int,@lastV int,@temV int,@I int,@J int
drop table #C
select identity(int,1,1) as iid,* into #C from B
declare cursora cursor for
select * from a order by id
open cursora
fetch next from cursora into @intida,@intaaa,@intbba
while @@fetch_status=0
begin
if @intaaa>@intbba
begin
set @temV=@intaaa
set @intaaa=@intbba
set @intbba=@temV
end
set @I=@intaaa
while @I<@intbba
begin
select @J=dbo.GetMinValue(@intida,@I,@intbba)
if (select count(*) from b where (case when aa<bb then aa else bb end)<=@I+1 and (case when BB<AA then AA else BB end)>=@J-1)=0
begin
insert into #C(id,aa,bb)values(@intida,@I+1,@J-1)
end
select @I=@J
end
fetch next from cursora into @intida,@intaaa,@intbba
end
close cursora
deallocate cursora
delete from #C where cast(id as varchar)+','+cast(aa as varchar)+','+cast(bb as varchar) in (
select cast(id as varchar)+','+cast(aa as varchar)+','+cast(bb as varchar) from b)
select * from #c order by iid
------结果
1 1002 1002
1 1051 1099
1 1901 1999
Top
18 楼CrazyFor(冬眠的鼹鼠)回复于 2002-12-26 11:33:48 得分 0
补充一下:
A
----
2 600 200
1 1001 2000
B
----
2 210 300
2 450 500
1 1100 1150
1 1151 1900
1 1003 1050
结果
------
1 1002 1002
1 1051 1099
1 1901 1999
2 201 209
2 301 449
2 501 599Top




