Oracle Order By Sorting:列值首先是字符,然后是数字
Oracle Order By Sorting: Column Values with character First Followed by number
我的列值为
AVG、ABC、AFG、3/M、150、RFG、567、5HJ
要求排序如下:
ABC,AFG,AVG,RFG,3/M,5HJ,150,567
有什么帮助吗?
不幸的是,排序顺序中的数字在字符之前。
我可以建议你在值前面添加一个额外的计算列,如果它们以数字开头,那么你将按该虚拟列
排序 'ZZZ'
如果没有大量的唯一值,构建一个具有该值的 table 和它的人工排序顺序,然后按排序键排序。类似于:
create table sort_map
( value varchar2(35),
sort_order number(4)
);
insert into sort_map (value, sort_order) values ('ABC',10);
insert into sort_map (value, sort_order) values ('AFG', 20);
....
insert into sort_map (value, sort_order) values ('150', 70);
insert into sort_map (value, sort_order) values ('567', 80);
--example query
select t.my_col, s.sort_order
from my_table t
join sort_map s
on (t.my_col = s.value)
order by s.sort_order;
如果您想在数字之前对字母进行排序,那么您可以测试每个字符。这是一种方法:
order by (case when substr(col, 1, 1) between 'A' and 'Z' then 1 else 2 end),
(case when substr(col, 2, 1) between 'A' and 'Z' then 1 else 2 end),
(case when substr(col, 3, 1) between 'A' and 'Z' then 1 else 2 end),
col
这不会产生请求的输出,但对于数字第二的字典 TRANSLATE
是一个简单的解决方案:
http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions196.htm
select value
from (
select 'AVG' as value from dual
union all
select 'ABC' as value from dual
union all
select 'AFG' as value from dual
union all
select '3/M' as value from dual
union all
select '150' as value from dual
union all
select 'RFG' as value from dual
union all
select '567' as value from dual
union all
select '5HJ' as value from dual
)
order by translate(upper(value), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ')
;
这会将所有字母和数字移到末尾。
A) 如果您只想更改完整数字序列的顺序,只需创建您的 isNumeric 函数:
SELECT * FROM table WHERE isNumeric(field) ORDER BY FIELD
UNION ALL
SELECT * FROM table WHERE NOT isNumeric(field) ORDER BY FIELD
B) 如果你想改变字符的顺序。
创建一个函数,在每个带有修饰符的字符前添加一个数字。
- 数量 -> 0
- 其他 -> 2
- 字母 -> 4
例如:
- shortHelper("2FT/") => "024F4T2/"
- shortHelper("AZ") => "4A4Z"
- shortHelper("Z1") => "4Z01"
然后使用“ORDER BY shortHelper(Field)
我的列值为
AVG、ABC、AFG、3/M、150、RFG、567、5HJ
要求排序如下:
ABC,AFG,AVG,RFG,3/M,5HJ,150,567
有什么帮助吗?
不幸的是,排序顺序中的数字在字符之前。 我可以建议你在值前面添加一个额外的计算列,如果它们以数字开头,那么你将按该虚拟列
排序 'ZZZ'如果没有大量的唯一值,构建一个具有该值的 table 和它的人工排序顺序,然后按排序键排序。类似于:
create table sort_map
( value varchar2(35),
sort_order number(4)
);
insert into sort_map (value, sort_order) values ('ABC',10);
insert into sort_map (value, sort_order) values ('AFG', 20);
....
insert into sort_map (value, sort_order) values ('150', 70);
insert into sort_map (value, sort_order) values ('567', 80);
--example query
select t.my_col, s.sort_order
from my_table t
join sort_map s
on (t.my_col = s.value)
order by s.sort_order;
如果您想在数字之前对字母进行排序,那么您可以测试每个字符。这是一种方法:
order by (case when substr(col, 1, 1) between 'A' and 'Z' then 1 else 2 end),
(case when substr(col, 2, 1) between 'A' and 'Z' then 1 else 2 end),
(case when substr(col, 3, 1) between 'A' and 'Z' then 1 else 2 end),
col
这不会产生请求的输出,但对于数字第二的字典 TRANSLATE
是一个简单的解决方案:
http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions196.htm
select value
from (
select 'AVG' as value from dual
union all
select 'ABC' as value from dual
union all
select 'AFG' as value from dual
union all
select '3/M' as value from dual
union all
select '150' as value from dual
union all
select 'RFG' as value from dual
union all
select '567' as value from dual
union all
select '5HJ' as value from dual
)
order by translate(upper(value), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ')
;
这会将所有字母和数字移到末尾。
A) 如果您只想更改完整数字序列的顺序,只需创建您的 isNumeric 函数:
SELECT * FROM table WHERE isNumeric(field) ORDER BY FIELD
UNION ALL
SELECT * FROM table WHERE NOT isNumeric(field) ORDER BY FIELD
B) 如果你想改变字符的顺序。
创建一个函数,在每个带有修饰符的字符前添加一个数字。
- 数量 -> 0
- 其他 -> 2
- 字母 -> 4
例如:
- shortHelper("2FT/") => "024F4T2/"
- shortHelper("AZ") => "4A4Z"
- shortHelper("Z1") => "4Z01"
然后使用“ORDER BY shortHelper(Field)