怎么取varchar2类型数据的最大值?

crl_lxy 2009-01-20 01:01:43
我有个table,有一列是varchar2类型的,要存'1.1.2'这样的数据,比如,这列原本有1.1~1.10的数据,我用
select max(wbs) from table查出来的最大值却是1.9,实际上应该是1.10,请问有什么方法可以拿到这类数据的最大值呢?
...全文
682 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
crl_lxy 2009-02-13
  • 打赏
  • 举报
回复
沒有比較明確的思路與解法哦,先結貼,有空再研究研究。。。。
AFIC 2009-02-06
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 crl_lxy 的回复:]
引用 22 楼 huang_xw 的回复:
把1.9换成1.09.
这样不是什么问题都解决了.


您可否幫忙給個具體方案?
[/Quote]

10g可以用正则匹配替换,有点像perl或者ruby的那种
不是的话照这个思路写函数,应该不过10行
lockhall 2009-02-06
  • 打赏
  • 举报
回复
继续关注~

hoho
SimpleYeah 2009-02-05
  • 打赏
  • 举报
回复
赞成~
这个是最快最方便的做法.

但如果原来数据库里面就已经有很多数据,那么只能用小数点为分界点.把每位的数值取出,然后以数值型进行比较了~
代码摆渡人 2009-02-04
  • 打赏
  • 举报
回复
把1.9换成1.09.
这样不是什么问题都解决了.
crl_lxy 2009-02-04
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 huang_xw 的回复:]
把1.9换成1.09.
这样不是什么问题都解决了.
[/Quote]

您可否幫忙給個具體方案?
crl_lxy 2009-02-04
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 xiaoxiao1984 的回复:]
简单的方法没有,倒是可以通过自定义聚合函数来实现,随便写了一个max_version的聚合函数,凑合看吧

SQL> select * from test;

ID
----------
1.2.1
1.1
1.2
1.10
1.12
1.1.2
1.1.1
1.1.12

8 rows selected.

SQL> select max_version(id) from test;

MAX_VERSION(ID)
--------------------------------------------------------------------------------
1.12

SQL>


create …
[/Quote]

看了頭有點大,嘿嘿,一定要這么做厚?
xiaoxiao1984 2009-02-04
  • 打赏
  • 举报
回复
简单的方法没有,倒是可以通过自定义聚合函数来实现,随便写了一个max_version的聚合函数,凑合看吧

SQL> select * from test;

ID
----------
1.2.1
1.1
1.2
1.10
1.12
1.1.2
1.1.1
1.1.12

8 rows selected.

SQL> select max_version(id) from test;

MAX_VERSION(ID)
--------------------------------------------------------------------------------
1.12

SQL>


create or replace function get_max_version
( value1 in varchar2,
value2 in varchar2
) return varchar2 is
v_num1 int;
v_num2 int;
v_pos int;
v_value1 varchar2(2000) ;
v_value2 varchar2(2000) ;
begin
v_value1 := value1;
v_value2 := value2;
if value1 is null or value1 = '' then
return value2;
elsif value2 is null or value2 = '' then
return value1;
else
while (length(v_value1) > 0 and length(v_value2) > 0) loop
v_pos := instr(v_value1, '.', 1, 1);
if v_pos > 0 then
v_num1 := to_number(substr(v_value1, 0, v_pos-1)) ;
v_value1 := substr(v_value1, v_pos+1);
else
v_num1 := to_number(v_value1);
v_value1 := '';
end if;
v_pos := instr(v_value2, '.', 1, 1);
if v_pos > 0 then
v_num2 := to_number(substr(v_value2, 0, v_pos-1)) ;
v_value2 := substr(v_value2, v_pos+1);
else
v_num2 := to_number(v_value2);
v_value2 := '';
end if;
if v_num1 > v_num2 then
return value1;
elsif v_num1 < v_num2 then
return value2;
end if;
end loop;
if length(v_value1) = 0 then
return value2;
else
return value1;
end if;
end if;
end;
/

create or replace type toversion as object
(
max_version varchar2(200),
static function ODCIAggregateInitialize
( actx in out toversion
) return number,
member function ODCIAggregateIterate
( self in out toversion,
value in varchar2
) return number,
member function ODCIAggregateTerminate
( self in out toversion,
returnValue out varchar2,
flags in varchar2
) return number,
member function ODCIAggregateMerge
( self in out toversion,
ctx2 in toversion
) return number
);
/

create or replace type body toversion as
static function ODCIAggregateInitialize
( actx in out toversion
) return number is
begin
actx := toversion('');
return ODCIConst.Success;
end;
member function ODCIAggregateTerminate
( self in out toversion,
returnValue out varchar2,
flags in varchar2
) return number is
begin
returnValue := self.max_version;
return ODCIConst.Success;
end;
member function ODCIAggregateIterate
( self in out toversion,
value in varchar2
) return number is
begin
if self.max_version is null then
self.max_version := value;
else
self.max_version := get_max_version(self.max_version, value);
end if;
return ODCIConst.Success;
end;
member function ODCIAggregateMerge
( self in out toversion,
ctx2 in toversion
) return number is
begin
self.max_version := get_max_version(self.max_version, ctx2.max_version);
return ODCIConst.Success;
end;
end;
/

create or replace function max_version
( x varchar2) return varchar2
parallel_enable
aggregate using toversion;
/

执行完成就好了,挺烦的,没想到啥好方法能支持较多层次的比较
自定义的好处就是逻辑定义语句好写好理解
阿三 2009-02-03
  • 打赏
  • 举报
回复
如果是1.1.2 两个小数点呢?

去除一个小数点吧,取最大值还是要转成数字再取max
gabriel80 2009-02-03
  • 打赏
  • 举报
回复
仙儿问的问题都夸年度啊。。去年的问题。。今天才看到答案。。
你真牛。。
同时。。我提下我的方案。。其实。。你可以用下移动小数点的方法。。
比如: 1.11×10比较完大小, 然后再除以10.还原数值。。这样不就可以了吗?如果10还不够就100,1000.。。。
当然我提的只是建议。。关键看你怎么做
tanzuwen 2009-02-03
  • 打赏
  • 举报
回复
继续关注!~
nitjump 2009-02-03
  • 打赏
  • 举报
回复
想啊想啊,想不出来,
hdxhdx_wdtx 2009-02-03
  • 打赏
  • 举报
回复
路过。没有想到解决办法。好久不写繁杂的SQL语句了。有点怀念过去的日子。
crl_lxy 2009-02-03
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 zxf_feng 的回复:]
如果是1.1.2 两个小数点呢?

去除一个小数点吧,取最大值还是要转成数字再取max
[/Quote]


小数点是没法去的哦,不然的话,如1.1.1.1和1.1.11岂不是相等了,1.1.15.1和1.1.1.5.1也相等了。。。呵呵。。。
crl_lxy 2009-02-03
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 gabriel80 的回复:]
仙儿问的问题都夸年度啊。。去年的问题。。今天才看到答案。。
你真牛。。
同时。。我提下我的方案。。其实。。你可以用下移动小数点的方法。。
比如: 1.11×10比较完大小, 然后再除以10.还原数值。。这样不就可以了吗?如果10还不够就100,1000.。。。
当然我提的只是建议。。关键看你怎么做
[/Quote]

嘿嘿,年前一直忙着买票回家,没怎么上来看。。。您说的解法有点繁琐哦,如果有NN个小数点,那移起来可就麻烦了。。。。
crl_lxy 2009-02-03
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 lockhall 的回复:]
如果是1.1.2 两个小数点呢?
[/Quote]


是的,table中的wbs列值会有多个小数点,例如1.1.1.1.1.1这样的,当然,还会有更长的。。。
jdsnhan 2009-02-02
  • 打赏
  • 举报
回复
分级解析吧
lockhall 2009-02-02
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 xiaoxiao1984 的回复:]
SQL> select to_number('1.12') from dual;

TO_NUMBER('1.12')
-----------------
1.12

SQL>
[/Quote]

select to_number('1.1.2') from dual;

如果是1.1.2 两个小数点呢?
xiaoxiao1984 2009-02-02
  • 打赏
  • 举报
回复
SQL> select to_number('1.12') from dual;

TO_NUMBER('1.12')
-----------------
1.12

SQL>
lockhall 2009-02-02
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 xiaoxiao1984 的回复:]
select max(to_number(wbs)) from table
[/Quote]

不知道函数 to_number 对于 1.1.2 这样的VARCHAR2类型转换的结果是多少?

这样转换会出错吧?
加载更多回复(8)

17,377

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 基础和管理
社区管理员
  • 基础和管理社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧