排序文本数据(如数字),以便遵循数值

时间:2013-06-07 15:57:10

标签: sql db2 alphanumeric

在数据库中,如果我有一个带有数字作为数据一部分的文本字段,并且我尝试排序,则数字不会按顺序返回,而是按字母顺序“伪”。

我'期待'这种行为并且对此很满意。但是,如果可能,用户已请求按字母顺序按字母顺序排序。

示例数据(已排序):

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”之前排序

4 个答案:

答案 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)