排序问题,想了好几天了...望高人指点

simulation123 2010-05-16 09:15:20
table1中字段CCM为字符串型
CCM
1
1-1
1-1-1
1-1-2
1-10
1-2

1-3
1-3-1
1-3-2
1-3-3
1-4
1-5
1-6
1-7
1-8
1-9
用select ccm from table1 order by ccm 得到的就是上面的结果,而我想要的结果是
1
1-1
1-1-1
1-1-2
1-2
1-3
1-3-1
1-3-2
1-3-3
1-4
1-5
1-6
1-7
1-8
1-9
1-10

怎么才能用一句话能把1-10放到1-9后面啊?或用其他方法解决
...全文
246 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
zdnest 2010-05-27
  • 打赏
  • 举报
回复
说个偷懒的方法:考虑你字符串的生成,使用固定长度字串,一来你查询方便,二来能提高效率。
luoyoumou 2010-05-26
  • 打赏
  • 举报
回复
-- ELSE部分有点小错误,修正一下:

CREATE OR REPLACE FUNCTION dot_lpad
(
v_char_col VARCHAR2, -- 将要填充的变量(字段)
v_sign VARCHAR2, -- 字段中的字符判断标识(你的例子中是句点(.))
bit_num NUMBER, -- 将要左填充的位数
fill_str VARCHAR2 -- 将要左填充的字符
)
RETURN VARCHAR2
AS
v_char_col2 VARCHAR2(4000);
v_loop NUMBER(4,0);
v_return VARCHAR2(4000);
BEGIN
v_char_col2 := v_sign||v_char_col||v_sign;
v_return := '';
v_loop := length(v_char_col2) - length(replace(v_char_col2,v_sign,''));
IF v_loop > 2 THEN
BEGIN
FOR i IN 1..v_loop LOOP
v_return := v_return||lpad( substr(v_char_col2,instr(v_char_col2,v_sign,1,i)+1,instr(v_char_col2,v_sign,1,i+1)-instr(v_char_col2,v_sign,1,i)-1),bit_num,fill_str);
END LOOP;
RETURN v_return;
END;
ELSE
RETURN substr(v_char_col2,2,length(v_char_col2)-2);
END IF;
END;
/

-----------------------------------------------------------------------------------------------------------
DROP TABLE test;

CREATE TABLE test(name VARCHAR2(40));

INSERT INTO test(name) VALUES('1.1');
INSERT INTO test(name) VALUES('1.1.1');
INSERT INTO test(name) VALUES('1.2.1');
INSERT INTO test(name) VALUES('1.101.5');
INSERT INTO test(name) VALUES('1.10.100.20.3');

COMMIT;

column name for a15
column name2 for a20
SELECT name,
dot_lpad(name,'.',4,'0') as name2
FROM test
ORDER BY dot_lpad(name,'.',4,'0') desc;


SELECT name,
dot_lpad(name,'-',4,'0') as name2
FROM test
ORDER BY dot_lpad(name,'-',4,'0') desc;
etsilence 2010-05-17
  • 打赏
  • 举报
回复
我来给个答案:
select ccm from (
select ccm,decode(length(ccm)-length(replace(ccm,'-')),0,ccm||'-0-0',1,ccm||'-0',2,ccm) c from tab_order)
order by to_number(substr(c,1,instr(c,'-',1,1)-1)),
to_number(substr(c,instr(c,'-',1,1)+1,instr(c,'-',1,2)-instr(c,'-',1,1)-1));

这个能够满足最多2个 - 号出现的情况,如果有三个 - ,则在decode里面再加一个判断,order by再加一个to_number就是了。
simulation123 2010-05-17
  • 打赏
  • 举报
回复
12楼的真牛

有没有人能提供其他人思路啊?

指定位数的话,有可能越界。
RunCanRun 2010-05-17
  • 打赏
  • 举报
回复
学习,周一到单位测试一下看看能不能解决呵呵
da21 2010-05-17
  • 打赏
  • 举报
回复
楼上的牛,应该可以,不过3楼,11楼的建议绝对支持!
etsilence 2010-05-17
  • 打赏
  • 举报
回复
补充下,如果有两个 - 号,则order by 中应该有三个to_number判断,我漏了一个,应该是这样:

select ccm from (
select ccm,decode(length(ccm)-length(replace(ccm,'-')),0,ccm||'-0-0',1,ccm||'-0',2,ccm) c from table1)
order by to_number(substr(c,1,instr(c,'-',1,1)-1)),
to_number(substr(c,instr(c,'-',1,1)+1,instr(c,'-',1,2)-instr(c,'-',1,1)-1)),
to_number(substr(c,instr(c,'-',1,2)+1,length(c)-instr(c,'-',1,2)));
luoyoumou 2010-05-17
  • 打赏
  • 举报
回复
select ccm,
ccm||'-0-0-0' ccmm,
lpad( substr(ccm||'-0-0-0', 1, instr(ccm||'-0-0-0','-')-1), 4, '0' ) as ccm1,
lpad( substr(ccm||'-0-0-0', instr(ccm||'-0-0-0','-',1,1)+1, instr(ccm||'-0-0-0','-',1,2)-instr(ccm||'-0-0-0','-',1,1)-1 ), 4, '0' ) as ccm2,
lpad( substr(ccm||'-0-0-0', instr(ccm||'-0-0-0','-',1,2)+1, instr(ccm||'-0-0-0','-',1,3)-instr(ccm||'-0-0-0','-',1,2)-1 ), 4, '0' ) as ccm3
from table1
ORDER BY lpad( substr(ccm||'-0-0-0', 1, instr(ccm||'-0-0-0','-')-1), 4, '0' ),
lpad( substr(ccm||'-0-0-0', instr(ccm||'-0-0-0','-',1,1)+1, instr(ccm||'-0-0-0','-',1,2)-instr(ccm||'-0-0-0','-',1,1)-1 ), 4, '0' ),
lpad( substr(ccm||'-0-0-0', instr(ccm||'-0-0-0','-',1,2)+1, instr(ccm||'-0-0-0','-',1,3)-instr(ccm||'-0-0-0','-',1,2)-1 ), 4, '0' );

---------------------------------------------------------------------------------------------------------------------------------------------------------
CCM CCMM CCM1 CCM2 CCM3
--------- ------------ ---------------- ------------------ --------------------
1 1-0-0-0 0001 0000 0000
1-1 1-1-0-0-0 0001 0001 0000
1-1-1 1-1-1-0-0-0 0001 0001 0001
1-1-2 1-1-2-0-0-0 0001 0001 0002
1-2 1-2-0-0-0 0001 0002 0000
1-3 1-3-0-0-0 0001 0003 0000
1-3-1 1-3-1-0-0-0 0001 0003 0001
1-3-2 1-3-2-0-0-0 0001 0003 0002
1-3-3 1-3-3-0-0-0 0001 0003 0003
1-4 1-4-0-0-0 0001 0004 0000
1-5 1-5-0-0-0 0001 0005 0000
1-6 1-6-0-0-0 0001 0006 0000
1-7 1-7-0-0-0 0001 0007 0000
1-8 1-8-0-0-0 0001 0008 0000
1-9 1-9-0-0-0 0001 0009 0000
1-10 1-10-0-0-0 0001 0010 0000

16 rows selected.
tangren 2010-05-17
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 wildwave 的回复:]

设计不合理..这样的话应该以1-01-01这样的方式储存
这里要那样排序的话,需要
order by 后面对ccm 应用substr(),instr(),to_number()..效率高不了
[/Quote]

估计一下你的每层次的数量来设计,三位不够四位
001-001-011
simulation123 2010-05-17
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 codearts 的回复:]
引用 4 楼 simulation123 的回复:
用substr不行啊!
“-”与“-”之间的长度是动态的,可能是三位,也可能是10十位
我不是用正则来解决你的动态问题了吗
[/Quote]

不好意思,我用的是oracle8i,不支持正则
minoboy 2010-05-17
  • 打赏
  • 举报
回复
查询语句真是复杂, 我觉得这个表设计的思路有点问题
dioryoo 2010-05-17
  • 打赏
  • 举报
回复
字符串的order by 好像排列是安ascii码排列的 全部看成是0-00-0 格式 substr 一点点判断吧 先判断0 然后判断 00 再判断最后面的零 ms用pl/sql写吧 高手试下吧 俺水平不够
codearts 2010-05-16
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 simulation123 的回复:]

用substr不行啊!
“-”与“-”之间的长度是动态的,可能是三位,也可能是10十位
[/Quote]


我不是用正则来解决你的动态问题了吗
simulation123 2010-05-16
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 wildwave 的回复:]
设计不合理..这样的话应该以1-01-01这样的方式储存
这里要那样排序的话,需要
order by 后面对ccm 应用substr(),instr(),to_number()..效率高不了
[/Quote]



指定1-01-01的话,一旦数量超过99就崩溃了
simulation123 2010-05-16
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 codearts 的回复:]
order by nvl(to_number(regexp_substr(CCM, '(\d+)', 1, 1)), 0),
nvl(to_number(regexp_substr(CCM, '(\d+)', 1, 2)), 0),
nvl(to_number(regexp_substr(CCM, '(\d+)', 1, 3)), 0)
[/Quote]

用substr不行啊!
“-”与“-”之间的长度是动态的,可能是三位,也可能是10十位
小灰狼W 2010-05-16
  • 打赏
  • 举报
回复
设计不合理..这样的话应该以1-01-01这样的方式储存
这里要那样排序的话,需要
order by 后面对ccm 应用substr(),instr(),to_number()..效率高不了
minoboy 2010-05-16
  • 打赏
  • 举报
回复
这个好象有点难....
很难用数字大小来排序...
看看楼下的专家有没有思路出来?
codearts 2010-05-16
  • 打赏
  • 举报
回复
order by nvl(to_number(regexp_substr(CCM, '(\d+)', 1, 1)), 0),
nvl(to_number(regexp_substr(CCM, '(\d+)', 1, 2)), 0),
nvl(to_number(regexp_substr(CCM, '(\d+)', 1, 3)), 0)

17,377

社区成员

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

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