某个表中有一个字段是英文的字符串,单词之间用空格隔开,需要统计其中单词的个数。难点有:
1,字符串中可能有数字,例如"I am 5 years old",数字算一个单词。因此例子中单词数为5;
2 , 分割单词的空格可能有一到多个,例如"This is fun"。例子中单词数为3;
Oracle中好像没有类似的函数。请教各位热心人,帮忙提供思路或参考语句。
Thanks in advance!
1,字符串中可能有数字,例如"I am 5 years old",数字算一个单词。因此例子中单词数为5;
2 , 分割单词的空格可能有一到多个,例如"This is fun"。例子中单词数为3;
Oracle中好像没有类似的函数。请教各位热心人,帮忙提供思路或参考语句。
Thanks in advance!
解决方案 »
- 一个sql
- 怎么用pl/sql语句 ,判断一个表,和序列是否存在,如果存在就删除,重建呢?
- 同时安装oracle8.0.5与oracle9i,如何解决tns端口冲突问题
- 事务回滚时,怎么使有的Sql语句不被rollback?
- 安裝 Oracle 9i R2 在Linux Advanced Server 3
- 对于oracle8.1.7 ,我如何才能装上“OLAP window Functions”?
- unix 下怎么查看数据表的主键?
- 跨表SUM()的问题
- Oracle中的数据库在哪存放着?
- 如何建立建立一个数据库(我的是在redhat7.2下的oracle8.17数据库),能不能给个例子
- 行转列,求解
- 利用OCI如何快速获取oracle spatial里的geometry信息
cnt number;
i number;
str varchar2(4000);
flag number; -- 上一个字符是否空格 1 是 0 不是
begin
str := a || ' ';
cnt := 0;
flag := 1;
for i in 1..length(str) loop
-- 如果遇到空格
if substr(str,i,1) = ' ' then
-- 判断前面是否是连续的空格,不是则认为新的单词
if flag = 0 then
cnt := cnt + 1;
end if;
end if;
if substr(str,i,1) = ' ' then
flag := 1;
else
flag := 0;
end if;
end loop; return cnt;
end ;
CREATE OR REPLACE FUNCTION get_words(word IN VARCHAR2 )
RETURN NUMBER
IS
num NUMBER:=0;
BEGIN
FOR i IN 1..Length(word) LOOP
IF SubStr(word,i,1) = Chr(32) THEN
num:=num+1;
END IF ;
END LOOP;
RETURN num+1;
END; SELECT get_words('I am 5 years old') FROM dual;
--忘记了你说不止一个空格,这个是最终版!OK!
CREATE OR REPLACE FUNCTION get_words(word IN VARCHAR2 )
RETURN NUMBER
IS
num NUMBER:=0;
BEGIN
FOR i IN 1..Length(word) LOOP
IF SubStr(word,i,1) = Chr(32) AND SubStr(word,i-1,1)!=Chr(32) THEN
num:=num+1;
END IF ;
END LOOP;
RETURN num+1;
END; SELECT get_words('I am 5 years old') FROM dual;
--补充:
--此函数可以过滤其他标点符号(如逗号,分号。。),只要标点符号紧跟在单词后面就OK!
CREATE OR REPLACE FUNCTION get_words(word IN VARCHAR2 )
RETURN NUMBER
IS
num NUMBER:=0;
BEGIN
FOR i IN 1..Length(word) LOOP
IF SubStr(word,i,1) = Chr(32) AND SubStr(word,i-1,1)!=Chr(32) THEN
num:=num+1;
END IF ;
END LOOP;
RETURN num+1;
END; --测试:
SELECT get_words('My name is paddy, I am 23 years old; I like CSDN.') words FROM dual; --结果:
WORDS
--------
12
谢谢,这个也是我最初想到的思路,我写的是这个样子的:
CREATE OR REPLACE FUNCTION get_char_count(src IN VARCHAR2, sep in varchar2)
RETURN number
IS
pcount number;
BEGIN
pcount := ((length(src) - length(replace(src, sep)))/length(sep) + 1);
return pcount;
END;
但是正如楼下所说的,对于多个空格的情况就不适用了!
显然还是欠缺
select length(REGEXP_REPLACE('My name is paddy, I am 23 years old, I like CSDN CUB.','[ ]*[[:alnum:]]+[ ]*','@')) from dual ;
返回16,正确应该是13
非常感谢你的回答!我认为你的答案是最完美的。我是个初选者,能否简单解释一下:
SubStr(word,i,1) = Chr(32) AND SubStr(word,i-1,1)!=Chr(32)
不胜感激!
---稍微变通下哈
---先使用regexp_replace('I am 5 year old', '\s+', '@')把所有的连续的空格字符用@代替
---剩下的思路就是你最初的想法
select length(regexp_replace('I am 5 year old', '\s+', '@')) -
length(regexp_replace(regexp_replace('I am 5 year old', '\s+', '@'),
'@',
'')) + 1
from dual
你说的可以过滤其他符号是不是要更改chr(32)变成其他字符?
as
num number:=0;
str varchar2(100);
j number;
begin
str:=trim(v_char);
select length(str||' ')-length(replace(str||' ',' ','')) into j from dual;
for i in 1..j loop
if instr(str,' ',1,i)!=instr(str,' ',1,i+1)-1 then
num:=num+1;
end if;
end loop;
return num;
end;--测试的结果SQL> select fun_sumzf2('I 2') from dual
2 /
FUN_SUMZF2('I2')
----------------
2
SQL> select fun_sumzf2('I 2 b') from dual
2 /
FUN_SUMZF2('I2B')
-----------------
3
SQL> select fun_sumzf2('I 2 b ') from dual
2 /
FUN_SUMZF2('I2B')
-----------------
3
SQL> select fun_sumzf2('2') from dual
2 /
FUN_SUMZF2('2')
---------------
1
这个很经典