如何在现有的表中利用年月生成一个顺序号?
http://expert.csdn.net/Expert/topic/3028/3028200.xml?temp=.1912805
问题点数:100、回复次数:18Top
1 楼zjcxc(邹建)回复于 2004-05-02 17:01:28 得分 0
UPDATE 表
SET dh =
(SELECT COUNT(*)
FROM 表
WHERE datediff(month, a.rq, rq) = 0 AND rq <= a.rq)
from 表 a
Top
2 楼zjcxc(邹建)回复于 2004-05-02 17:02:29 得分 0
你举例说明你要什么格式?
序号不对是什么意思? 不是按年月相同的按rq从小到大生成序号吗?
Top
3 楼zjcxc(邹建)回复于 2004-05-02 17:10:13 得分 0
--生成格式为RK04040001的序号,至于你说的序号不对,得举例说明了:
UPDATE 表 SET dh='RK'+convert(char(4),getdate(),12)+right(10000
+(SELECT COUNT(*) FROM 表 WHERE datediff(month,a.rq,rq)=0 AND rq <= a.rq),4)
from 表 a
Top
4 楼stadong(愚笨)回复于 2004-05-02 17:20:02 得分 0
生成的是这样的 select * from table order by rq,dh后
rk dh
1933/04/22 RK33040002
1933/04/22 RK33040002
RK33040002 RK00010001
2001/04/03 RK01040003
2001/04/03 RK01040003
2001/04/03 RK01040003
2001/04/04 RK01040011
2001/04/04 RK01040011
2001/04/04 RK01040011
2001/04/04 RK01040011
2001/04/04 RK01040011
2001/04/04 RK01040011
2001/04/04 RK01040011
2001/04/04 RK01040011
2001/04/05 RK01040015
2001/04/05 RK01040015
2001/04/05 RK01040015
2001/04/05 RK01040015
2001/04/06 RK01040023
.
.
.
这种情况,为什么?
格式是这样的,我想序号是每年每月重新从一开始,如:RK01040001, RK01040002...下月就是RK01050001 RK01050002Top
5 楼stadong(愚笨)回复于 2004-05-02 17:21:32 得分 0
UPDATE rk_bak
SET rkdh = 'RK' + CONVERT(char(4), rkrq, 12) + RIGHT(10000 +
(SELECT COUNT(*)
FROM rk_bak
WHERE datediff(month, a.rkrq, rkrq) = 0 AND rkrq <= a.rkrq), 4)
FROM rk_bak a
我是这么做的Top
6 楼stadong(愚笨)回复于 2004-05-02 17:48:41 得分 0
上面的写错了
1933/04/22 RK33040002
1933/04/22 RK33040002
2000/01/01 RK00010001
2001/04/03 RK01040003
2001/04/03 RK01040003
2001/04/03 RK01040003
2001/04/04 RK01040011
2001/04/04 RK01040011
2001/04/04 RK01040011
2001/04/04 RK01040011
2001/04/04 RK01040011
2001/04/04 RK01040011
2001/04/04 RK01040011
2001/04/04 RK01040011
2001/04/05 RK01040015
2001/04/05 RK01040015
2001/04/05 RK01040015
2001/04/05 RK01040015
2001/04/06 RK01040023Top
7 楼zjcxc(邹建)回复于 2004-05-02 18:01:53 得分 0
--因为你的日期有重复啊,如果你的日期有重复,但日期已经按顺序排列的话,可以用这样的语句:
--更新处理
declare @rq datetime,@i int
update rk_bak set @i=case datediff(month,rkrq,@rq) when 0 then @i+1 else 10001 end
,rkdh='RK'+CONVERT(char(4),rkrq,12)+right(@i,4)
,@rq=rkrq
Top
8 楼zjcxc(邹建)回复于 2004-05-02 18:02:00 得分 0
--测试
--测试数据
create table rk_bak(rkrq datetime,rkdh char(10))
insert rk_bak(rkrq)
select '1933/04/22'
union all select '1933/04/22'
union all select '2000/01/01'
union all select '2001/04/03'
union all select '2001/04/03'
union all select '2001/04/03'
union all select '2001/04/04'
union all select '2001/04/04'
union all select '2001/04/04'
union all select '2001/04/04'
union all select '2001/04/04'
union all select '2001/04/04'
union all select '2001/04/04'
union all select '2001/04/04'
union all select '2001/04/05'
union all select '2001/04/05'
union all select '2001/04/05'
union all select '2001/04/05'
union all select '2001/04/06'
go
--更新处理
declare @rq datetime,@i int
update rk_bak set @i=case datediff(month,rkrq,@rq) when 0 then @i+1 else 10001 end
,rkdh='RK'+CONVERT(char(4),rkrq,12)+right(@i,4)
,@rq=rkrq
go
--显示处理结果
select * from rk_bak
go
--删除测试
drop table rk_bak
/*--测试结果
rkrq rkdh
------------------------------------------------------ ----------
1933-04-22 00:00:00.000 RK33040001
1933-04-22 00:00:00.000 RK33040002
2000-01-01 00:00:00.000 RK00010001
2001-04-03 00:00:00.000 RK01040001
2001-04-03 00:00:00.000 RK01040002
2001-04-03 00:00:00.000 RK01040003
2001-04-04 00:00:00.000 RK01040004
2001-04-04 00:00:00.000 RK01040005
2001-04-04 00:00:00.000 RK01040006
2001-04-04 00:00:00.000 RK01040007
2001-04-04 00:00:00.000 RK01040008
2001-04-04 00:00:00.000 RK01040009
2001-04-04 00:00:00.000 RK01040010
2001-04-04 00:00:00.000 RK01040011
2001-04-05 00:00:00.000 RK01040012
2001-04-05 00:00:00.000 RK01040013
2001-04-05 00:00:00.000 RK01040014
2001-04-05 00:00:00.000 RK01040015
2001-04-06 00:00:00.000 RK01040016
(所影响的行数为 19 行)
--*/Top
9 楼zjcxc(邹建)回复于 2004-05-02 18:08:32 得分 100
--如果你的表中rkrq无序,而且可能重复的话,那你就在你的表中加一个标识字段来处理(下面假设你的标识字段名为id,当然,如果表中有主键,可以直接用主键代替id)
update rk_bak set rkdh='RK'+CONVERT(char(4),rkrq,12)
+right(10000+(
select count(*) from rk_bak
where datediff(month,rkrq,a.rkrq)=0 and rkrq<a.rkrq
or(rkrq=a.rkrq and id<=a.id)
),4)
from rk_bak aTop
10 楼zjcxc(邹建)回复于 2004-05-02 18:09:14 得分 0
--测试
--测试数据
create table rk_bak(id int identity(1,1),rkrq datetime,rkdh char(10))
insert rk_bak(rkrq)
select '1933/04/22'
union all select '1933/04/22'
union all select '2000/01/01'
union all select '2001/04/03'
union all select '2001/04/03'
union all select '2001/04/03'
union all select '2001/04/04'
union all select '2001/04/04'
union all select '2001/04/04'
union all select '2001/04/04'
union all select '2001/04/04'
union all select '2001/04/04'
union all select '2001/04/04'
union all select '2001/04/04'
union all select '2001/04/05'
union all select '2001/04/05'
union all select '2001/04/05'
union all select '2001/04/05'
union all select '2001/04/06'
go
--更新处理
update rk_bak set rkdh='RK'+CONVERT(char(4),rkrq,12)
+right(10000+(
select count(*) from rk_bak
where datediff(month,rkrq,a.rkrq)=0 and rkrq<a.rkrq
or(rkrq=a.rkrq and id<=a.id)
),4)
from rk_bak a
go
--显示处理结果
select * from rk_bak
go
--删除测试
drop table rk_bak
/*--测试结果
id rkrq rkdh
----------- ------------------------------------------------------ ----------
1 1933-04-22 00:00:00.000 RK33040001
2 1933-04-22 00:00:00.000 RK33040002
3 2000-01-01 00:00:00.000 RK00010001
4 2001-04-03 00:00:00.000 RK01040001
5 2001-04-03 00:00:00.000 RK01040002
6 2001-04-03 00:00:00.000 RK01040003
7 2001-04-04 00:00:00.000 RK01040004
8 2001-04-04 00:00:00.000 RK01040005
9 2001-04-04 00:00:00.000 RK01040006
10 2001-04-04 00:00:00.000 RK01040007
11 2001-04-04 00:00:00.000 RK01040008
12 2001-04-04 00:00:00.000 RK01040009
13 2001-04-04 00:00:00.000 RK01040010
14 2001-04-04 00:00:00.000 RK01040011
15 2001-04-05 00:00:00.000 RK01040012
16 2001-04-05 00:00:00.000 RK01040013
17 2001-04-05 00:00:00.000 RK01040014
18 2001-04-05 00:00:00.000 RK01040015
19 2001-04-06 00:00:00.000 RK01040016
(所影响的行数为 19 行)
--*/Top
11 楼stadong(愚笨)回复于 2004-05-02 18:56:23 得分 0
我试验了100条的数据,正确,现在我在运行一万条的数据,几分钟也没完成,我还有一个10万条的不知道能不能行Top
12 楼stadong(愚笨)回复于 2004-05-02 20:23:31 得分 0
10万条的数据已经运行1小时12分钟了Top
13 楼zjcxc(邹建)回复于 2004-05-02 21:47:56 得分 0
你用的是那种方法? 如果是:
update rk_bak set rkdh='RK'+CONVERT(char(4),rkrq,12)
+right(10000+(
select count(*) from rk_bak
where datediff(month,rkrq,a.rkrq)=0 and rkrq<a.rkrq
or(rkrq=a.rkrq and id<=a.id)
),4)
from rk_bak a
那效率就低.你在rkrq上建立聚集索引,然后用下面这种方法吧:
declare @rq datetime,@i int
update rk_bak set @i=case datediff(month,rkrq,@rq) when 0 then @i+1 else 10001 end
,rkdh='RK'+CONVERT(char(4),rkrq,12)+right(@i,4)
,@rq=rkrqTop
14 楼stadong(愚笨)回复于 2004-05-02 22:08:38 得分 0
我终于用一近三个小时把这个转换做完了!看到您的做法了,不过什么是聚集索引呢?不好意思,我不明白!Top
15 楼zjcxc(邹建)回复于 2004-05-02 22:15:27 得分 0
聚集索引是索引的一种,不过,聚集索引可以让表中记录的存储顺序按照聚集索引来排列. 这样就满足了上述处理方法中的: 日期已经按顺序排列
因为创建聚集索引,记录要按聚集索引重新排列存储,所以在数据量大时,创建聚集索引也比较慢. 但这样创建后,你以后再做这样的处理就快了.
但如果你只做一次这个工作,也没必要.Top
16 楼stadong(愚笨)回复于 2004-05-02 22:16:41 得分 0
我明白了Top
17 楼stadong(愚笨)回复于 2004-05-02 22:26:33 得分 0
快得不得了,只用了不到一分钟,10万数据!
问题解决了,顺便说两句,我已经奔四十的人了,可是对程序情有独钟,我虽然是学计算机专业的,但是一直没有做很系统的程序,现在也是业余时间搞点小程序,人总是要上进的,以前我听说过了三十岁就不能当程序员了,所以一直没有好好静下心来,可现在功利心没有了,只是想学一点算一点,就当是爱好了!
这里我常来, zjcxc(邹建) 的大名我常看到,以前未曾得到指教,这是我的第一问题,可能对于您来讲很简单,但对我来说,帮我解决了一个不小的问题,虽然我能利用别的方法写程序解决,但都是需要很长的时间,都是些笨的方法,我对sql只知道了一点点,找了好多贴子,就是没找到解决的方法,今天晚上解决,非常感谢!
同时我也想说,可能这些问题对你们高手没什么的,但对我这种门外汉来说,不知道有多高兴呢!我由衷的说一句,这里的风气真好,zjcxc(邹建)你是好样的!Top
18 楼zjcxc(邹建)回复于 2004-05-02 22:30:14 得分 0
呵呵,你太客气了.
解决不同的问题,对于我来说,也是一种提升Top




