在数据库中,如果我有一个带有数字作为数据一部分的文本字段,并且我尝试排序,则数字不会按顺序返回,而是按字母顺序“伪”。
我'期待'这种行为并且对此很满意。但是,如果可能,用户已请求按字母顺序按字母顺序排序。
示例数据(已排序):
100
1001
1110
1010101E
2
200
22ER
Abd
Bre
客户 - 希望“2”在“100”之前排序,而“200”在“1001”之前排序 这变得粘滞的地方是数字/字母组合发生的地方。这个问题是由于这样一个事实,即被命名的项目可以被命名为任何东西(“Box-one”,“Box 1”,“Box1”,“1Box”“1”等......),如“firstname”排序,但许多人将他们的孩子命名为数字 - 排序是一场噩梦。
我已经玩弄了所有“仅限数字”字段的UNION,转换为数字并排序,然后与alpha-nums联合的想法......所以至少这些数字是“按预期“ - 但开销似乎太过分了。
根据用户的要求,我希望“2erd”应该在“100”之前排序,而“22Asd”会在“22asd”之前排序
有任何建议或解决方案吗?这必须出现。 我们正在使用DB2 v9.5
前导零也是“问题”,因为“0000123”在“122”之前排序
答案 0 :(得分:1)
我没有方便的9.5实例,但这应该有效,因为它只使用DB2 9.5中提供的功能:
db2 => with input (f) as (
values ('100'), ('1001'), ('1110'), ('1010101E'),
('2'), ('200'), ('22ER'), ('Abd'), ('Bre')
)
select * from input
order by case
when
length(trim(translate(f,'','ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'))) = 0
then 9999999999999 -- alpha only; make sure it sorts after all numbers
else
integer(trim(translate(f,'','ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'))) -- convert to integer
end, -- this column is numeric
case
when
length(trim(translate(f,'','ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'))) = 0
then f -- alpha only
else '' -- nothing; sorts before other strings
end
;
F
--------
2
22ER
100
200
1001
1110
1010101E
Abd
Bre
9 record(s) selected.
TRANSLATE函数用于从列值中删除非数字字符,允许您以数字方式对剩余数据进行排序。
答案 1 :(得分:0)
如果您使用的是MySQL,则可以执行以下操作:
order by field+0, field
MySQL会自动对字符串中最左边的字符进行转换以进行算术运算。
在其他数据库中,这似乎更难。在某些情况下,您可以使用REGEXP替换模式(例如删除第一个非数字后的所有字符)。或者,你可能需要循环遍历角色本身,例如:
order by (case when left(field, 5) not like '[^0-9]' then cast(left(field, 5) as int)
when left(field, 4) not like '[^0-9]' then cast(left(field, 4) as int)
when left(field, 3) not like '[^0-9]' then cast(left(field, 3) as int)
when left(field, 2) not like '[^0-9]' then cast(left(field, 2) as int)
when left(field, 1) not like '[^0-9]' then cast(left(field, 1) as int)
end), field
答案 2 :(得分:0)
另一种方法是修剪和右对齐你的字符串。假设你的专栏是20个字符宽。你可以使用像
这样的东西right(repeat(' ',20)||trim(yourdata),20)
当然,如果字符串以非数字字符开头,则不能很好地工作。
答案 3 :(得分:0)
你能做点什么(假设sortfield小于11个字符,如果它更长 你需要增加零和截断点的数量或进行测试):
按右方排序(concat(“0000000000”,sortField),10)