SQL高难度问题(100分)

  • 主题发起人 主题发起人 coolfun
  • 开始时间 开始时间
C

coolfun

Unregistered / Unconfirmed
GUEST, unregistred user!
请问怎样用SQL语句实现如下功能:

有一个表,有2个字段,2个字段为字符型,第一个字段有数据,第二个字段为空.

并且第一个字段前几位是字母,后几位是数字或者其他符号(不会出现字母).

现在我想把第一个字段中的字母复制到第二个字段中.

例:
原表:
field1 field2
R24
TP234
FRT543
DSET3.3
.
.
.
 
第一个字段前几位是字母的位数是固定的吗?
 
TO sunys:

就是不固定!!!
 
不难吧。。
找前面几个字母然后UPDATE表。。。
 
哈哈,一會兒再回答你![8D][8D][8D]
 
不是什么都可以用SQL解决的,不然用SQL写程序就好了
还要开发软件干什么。如果是ORACLE,用PL/SQL很快
 
真還有點難呢,case
 
我想SQL语句也可以实现的。。。

把字段值读出
再找出第一个数字开头的位置(这好像比较麻烦,从第一个开始一个一个比较是否是
数字了),然后取前面的子串。。

不是最好的办法,
不过可以实现
 
不用SQL语句当然可以实现,只是我的数据库的有100多万条数据,实在太慢了,几乎运行不了.
用SQL语句会快许多的.有人会吗?
 
用一个存储过程
建立一个游标
循环判断


DECLARE CUR_SER CURSOR FOR
SELECT Field1,Field2 from Table1
open cur_sur
declare @field1_value char(50)
declare @field2_value char(50)
declare @len int
declare @num int
fetch next form cur_ser into @field1_value, @field2_value
while (@@fetch_status=0)
begin
select @num=1
select @len=len(@field1_value)
while (@num<=@len)
begin
if upper(substring(@field1_value,@num,1))>'A'
and upper(substring(@field1_value,@num,1))<'Z'
select @num=@num+1
else
begin
select @field2_value=substring(@field1_value,@num+1,@len-@num-1)
exit
end
end
update Table1
set field2=@field2_value
where field1=@field1_value
end

意思到了!可能会有个别语句问题,你自己琢磨吧!
 
不知道你的是什么数据库啊,可惜mssql数据库不能用 translate 函数。如果是orcale就好办了。
 
TO luckywzy:
非常感谢你的忙,在你的基础上,我稍微作了一下修改,现程序正在执行过程中,如果结果
正确,就等着拿分吧,再次感谢.
 
update table field2=REPLACE(field1,
(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(field1,
'a', ''), 'b', ''), 'c', ''), 'd', ''), 'e', ''), 'f', ''), 'g', ''), 'h', ''), 'i', ''), 'j', ''), 'k', ''), 'l', ''), 'm', ''),
'n', ''), 'o', ''), 'p', ''), 'q', ''), 'r', ''), 's', ''), 't', ''), 'u', ''), 'v', ''), 'w', ''), 'x', ''), 'y', ''), 'z',
'')), '')
如果是 ORCALE数据库,translate 将会使上面的语句简单的很多,上面是MSSQL运行中通过。
可能比较烦琐
 
TO sunys:

真是很佩服你啊.不过还是有点小问题,也许是我没有说清楚的缘故.

就是还有一种情况没有考虑到,比如:

TP321BA/3

用你的方法对于这种情况,得到的结果是TP321BA/3,而不是我要的结果:TP

还有,我也不怎么懂你这种方法的原理,能稍微解释一下吗?谢谢了

TO luckywzy:

你的方法还有点问题,好像中间有个死循环,得不到预期的结果!
 
to coolfun:
我上面代码中的exit应改为break
如果还不行, 你把你改的存储过程贴出来!
 
另外,你这个TABLE中最好增加一列作为关键字,这样最后的Updata的where
条件就可以指定唯一行,语句就不会有更改多行的情况
 
CREATE PROCEDURE [dbo].[xiefeng] AS
DECLARE CUR_SER CURSOR FOR
SELECT top 2 call_no,leibie from xf
open cur_ser
declare @call_no_value char(50)
declare @leibie_value char(50)
declare @len int
declare @num int
fetch next from cur_ser into @call_no_value, @leibie_value
while (@@fetch_status=0)
begin
select @num=1
select @len=len(@call_no_value)
while (@num<=@len)
begin
if upper(substring(@call_no_value,@num,1))>'A'
and upper(substring(@call_no_value,@num,1))<'Z'
select @num=@num+1
else
begin
select @leibie_value=substring(@call_no_value,1,@num-1)
select @num=@len+1
end
end
update xf
set leibie=@leibie_value
where call_no=@call_no_value
end
GO
 
如果是SQL server2000,可以写一个函数,再在update中调用函数实现这个功能.6.5就不行了
 
while (@num<=@len)
begin
if upper(substring(@call_no_value,@num,1))>'A'
and upper(substring(@call_no_value,@num,1))<'Z'
select @num=@num+1
else
begin
select @leibie_value=substring(@call_no_value,1,@num-1)
select @num=@len+1
end
end
______________________________________________________________
改为:
while (@num<=@len)
begin
      if upper(substring(@call_no_value,@num,1))>'A'
and upper(substring(@call_no_value,@num,1))<'Z'
select @num=@num+1
else
begin
select @leibie_value=substring(@call_no_value,1,@num)
break
end
end

------------------------------
 
我想到了一个可行的方法。不用游标,多写几个SQL即可。
 
原理就是先把你里面的所含的字母变成空( '')
比如你的 field1的一个值为'babvad3455';
REPLACE(field1, 'a', '') 的结果为'bbvd2445' ,然后再replace(bbvd2445,'b','')把
'b'也去掉,接下去同理是把所有的字母全部去掉,剩下就是 '3445'了,
然后再把Field 的babvad3455中的'2445'变为空就得到'babvad',也就是剩下的字母了。

对于TP321BA/3 这个特殊的,用我的方法应该不行的了,

 
后退
顶部