• 全部
  • 基础类
  • 应用实例
  • 新技术前沿

高分求解决方法和算法

Rubi 2006-06-08 10:32:16
昨天其实问过了,但是实现效率太低,这里就把需求说说,然后请大家帮忙想想

有A,B两个表,需要相互比较,找出A,B中不相等的数据,要比较两次,A在B中没有的,B在A中没有的,然后找出这些数据,两个表的结构如下:
A: B:
1340000 1349
1340001 13533
1340002 13716
1340003 13717
1340004 13718
1340005 13761
1340006
1340007
1340008
1340009
1340010
1340011
1340012
1340013
1340014
1340015
1340016
1340017
1340018
1340019

... ...
A中都是7位数,而B中有7位,也有非7位的.
例如B中的1349实际上相当于从1349000~1349999之间的所有数据.13533相当于1353300~1353399之间所有数据.依次类推.

/*
我把B数据不满7位的拆开为7位把B全部转换为标准的7位数据,在和A中的比较,这样用sql语句查询就比较方便,但是这样做速度实在是太慢,这个是我的思路,不知道大家能否提供其他思路或者优化的算法吗?
*/

希望大家能帮忙,做了好几天了,自己算法能力有限,实在想不出来了
...全文
494 点赞 收藏 41
写回复
41 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
wwh999 2006-06-12
又有8位的?
你现在是不是想:
1>把区位段的去掉重复?(上面说的取最短值?)
2>根据1中所得,生成关于此区位段的号码,然后再与你的BOSS表中的进行对比?不是与真实的号码对比吗?
即是1表中去重复后,假设行为1349,那么要生成13490000001~1349999999共计9999999条临时记录,然后在号码表中对比查找,看这9999999条中,有哪些漏掉了的..是吗?

回复
Rubi 2006-06-12
恩,你的那个去重复的游标我还没有用,我只是用了我的游标,也要三分钟才能把数据小于7位的变成标准的7位,我现在又想了个办法,在程序里来处理,直接把小于7位的变成标准的7位,然后变成文本,在导入数据库中,那么现在剩下的就是标准的7位,和大于7位的数据了,速度倒是上来,只是现在8位的数据怎么比较就有点郁闷拉!

wwh999(印钞机的卖 V2.0...发梦ing):
太感谢你了!一直帮我解决这个问题在
回复
wwh999 2006-06-12
你现在的问题,解决了吗?

关于去重复的问题,你看一下我的贴:
http://community.csdn.net/Expert/topic/4811/4811009.xml?temp=.2988245

上面有邹老大的回复,一条SELECT可以搞掂。不过一样需要两个多钟头...处理了43000条左右了.
回复
Rubi 2006-06-11
数据库已经发给你了!
说明都在E-mail中呢!
然后就是比较找出那两个表中相互没有的数据,我写了一个存储过程,里面用到了以前你曾经给过我的一个方法,你可以去看看,哪个方法把hlrt表里面所有不足7位和满7位的数据都插入到另外一个表中,不足7位的按照我上面提供的规律作成7位了,现在就是那个A表(Boss)中有8位的,我还要相办法看是怎么做呢
回复
king24 2006-06-11
我的回答是,我告诉你
回复
wwh999 2006-06-11
我那个去重复的游标你还是不要用了吧,你的数据量太大了,我已经让它游了一个小时,电脑完全处于半死机状态...CPU占用率100%....

两张表都接近6W条数据,进行处理,,,处理记录将会以亿来计算....没招。已经找了几个三星四星的...暂时没有更好的解决方法。

我现在开始怀疑你的业务逻辑是不是有问题了...太慢了,准备停掉过程重启了!
回复
wwh999 2006-06-10
还有,邮件已经收到,txt文件和excel文件中,都是些什么,还有你究竟需要达到什么样的效果,请你讲清楚一些..
还有,你需要的格式是在SQL中,还是在EXCEL中?你要的最终格式?
你最好是把数据库做一个副本,在副本中的其它表全部干掉,仅留要测试效果的,MAIL给我,我好测试...
回复
wwh999 2006-06-10
--原表数据
bID
----------
1349
1376
13533
13716
13717
13718
13761
1349178
1376899
13768
13491
137166

(所影响的行数为 12 行)

--得到的结果集
bID
----------
1349
1376
13533
13716
13717
13718

--这个效果应该是达到你在Message中发来的要求了..,本来想用select来写,后来发现写不出,还在CSDN上发了一个贴,居然也是没人答得出,你可以参考一下:
http://community.csdn.net/Expert/topic/4811/4811009.xml?temp=5.936831E-02
回复
wwh999 2006-06-10
写了一个游标,用来完成: 去除范围重复的段号码(取最大范围的):
---------------------------------------------------------------------------------
USE PUBS
if exists(select * from sysobjects where name='Tb' and xtype='U') drop table Tb
GO
--生成测试用数据,为SELECT初始环境
CREATE TABLE Tb(bID varchar(10))
INSERT INTO Tb SELECT '1349'
UNION ALL SELECT '1376'
UNION ALL SELECT '13533'
UNION ALL SELECT '13716'
UNION ALL SELECT '13717'
UNION ALL SELECT '13718'
UNION ALL SELECT '13761'
UNION ALL SELECT '1349178'
UNION ALL SELECT '1376899'
UNION ALL SELECT '13768'
UNION ALL SELECT '13491'
UNION ALL SELECT '137166'

--select * from Tb where len(bid) in (select min(len(bid)) from Tb)
select * into #temp from Tb
select * from #temp
GO

Declare @sql varchar(8000),@cNo varchar(1000)
Declare pr_CURSOR CURSOR FOR SELECT * FROM #TEMP
OPEN pr_CURSOR
FETCH FROM pr_CURSOR into @cNo
WHILE @@FETCH_STATUS=0
BEGIN
set @sql='Delete B from Tb B where B.bid in (select * from Tb where bid like'''+@cNo+'%'' and bid<>'''+@cNo+''')'
exec (@sql)
FETCH NEXT FROM pr_CURSOR into @cNo
END
CLOSE pr_CURSOR
DEALLOCATE pr_CURSOR

GO
select * from Tb
drop table #temp,Tb
回复
fest 2006-06-09
楼主,这样的算法是否可行?

要排除的记录集是: (A==B)|| ((A/10 )==B)

在原数据库中选取这个集合除外的其他数据应该就是所要检索的
回复
十一月猪 2006-06-09
关注
回复
sclzmbie 2006-06-09
Maybe you should implement your algorithm in C instead of SQL.
回复
Rubi 2006-06-09
13500920
13500921
13500922
13500923
13500924
13500925
13500926
13500927
13500928
13500929
13500970
13500971
13500972
13500973
13500974
13500975
13500976
13500977
13500978
13500979


上面的数据,我如何写成 1350092 ,10
1350097 ,10
,就是统计前7个数一样 ,一共有多少个这样的数的查询?
回复
Rubi 2006-06-09
是阿,呵呵,昨天又发现了一个郁闷的问题,本来表A都是标准的7位,现在发现有8位了,我现在要想办法怎么才能把8位的和B表的数据比较:
1,把8位合并为7位,在比较,
2,直接把8位数据的前7位提取出来和B表相比,然后如果有,在看这8位数据是否是连续的10个数,如果不是,则把没有连续的地方找出来

算法真实麻烦,
回复
wwh999 2006-06-09
我一看上面测试代码怎么这么眼熟呢....呵呵...
继续关注一下,写个过程来规范一下B表,楼上的各位,可能都还没有明白LZ想要干嘛..!
回复
fcuandy 2006-06-09

SELECT B.Num Num,'B' Frm,IDENTITY(int) id INTO #tb FROM TableB B WHERE NOT EXISTS(SELECT * FROM TableA A WHERE B.Num=LEFT(A.Num,LEN(B.NUM)))
INSERT #tb SELECT A.Num,'A' FROM TableA A WHERE NOT EXISTS(SELECT * FROM TableB B WHERE B.Num=LEFT(A.Num,LEN(B.Num)))
DECLARE @i int,@n int,@CurNum int,@frm char(1),@mi int,@mx int
SELECT @i=COUNT(*) FROM #tb-- WHERE Frm='A'
SET @n=1
SET @frm=''
WHILE @n<=@i
BEGIN
SELECT @CurNum=Num,@frm=RTRIM(Frm) FROM #tb WHERE id=@n
SET @n=@n+1
IF @frm='A'
BEGIN
PRINT @CurNum
END
Else
BEGIN
SET @mi=CAST(RTRIM(CAST(@CurNum AS CHAR(7))) + REPLICATE('0',7-LEN(@CurNum)) AS INT)
SET @mx=CAST(RTRIM(CAST(@CurNum AS CHAR(7))) + REPLICATE('9',7-LEN(@CurNum)) AS INT)
PRINT CAST(@mi AS CHAR(10))+ '--' + CAST(@mx AS CHAR(10))
END
SET @frm=''
END
DROP table #tb
回复
Rubi 2006-06-09
to:fest(fest)
你的A/10==B这样做也可以,但是我还是要找出是否有10条,而且10天必须连续阿
回复
j9988 2006-06-08
每次都临时生成记录,这样速度不是更慢?

客户输入1349,你就得在表内生1349000到1349999一万条记录.这样查询就快了.

因为客户输入是一次性的,你也就一次性生成.生成一万条记录也很快.

而查询是时刻都会有的. 这时你不论用什么高效的办法.都得生成B表内简略数据相对应的几万到几十万条甚至上百万记录.

两种效率比较不是很显然吗??

回复
Rubi 2006-06-08
因为B标中有1345等不足7位的,我的思路就是把不足7位的还原为7位,插入到临时表,然后临时表就是都为7位的标准数据,然后再和A表的标准7位比较,那么就用sql查询,速度岂不是快了很多吗?
回复
wwh999 2006-06-08
那這個跟B表有什麼關系?....你要找出的數據跟這個又有什麼關系?
回复
加载更多回复
相关推荐
发帖
MS-SQL Server
创建于2007-09-28

3.3w+

社区成员

MS-SQL Server相关内容讨论专区
申请成为版主
帖子事件
创建了帖子
2006-06-08 10:32
社区公告
暂无公告