1

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

我“期待”这种行为并且对此感到满意。但是,如果可能,用户已请求按数字和字母顺序对事物进行排序。

示例数据(已排序):

100
1001
1110
1010101E
2
200
22ER
Abd
Bre

客户希望“2”在“100”之前排序,而“200”在“1001”之前排序,这会变得粘稠,这是数字/字母组合出现的地方。这个问题是因为被命名的项目可以命名为任何东西(“Box-one”、“Box 1”、“Box1”、“1Box”、“1”等),比如按“名字”排序,但是许多人给他们的孩子取一个数字——分类是一场噩梦。

我玩弄了对所有“仅数字”字段进行 UNION 的想法,将其转换为数字并排序,然后与 alpha-nums 联合...所以至少这些数字是“如预期的那样” - 但是开销似乎离谱。

根据用户的请求,我希望“2erd”应该在“100”之前排序,而“22Asd”应该在“22asd”之前排序

有什么建议或解决方案吗?这必须出现。我们正在使用 DB2 v9.5

前导零也是一个“问题”,因为“0000123”在“122”之前排序

4

4 回答 4

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 函数用于从列值中删除非数字字符,允许您对剩余数据进行数字排序。

于 2013-06-07T18:05:01.720 回答
0

你可以做类似的事情(假设 sortfield 小于 11 个字符,如果它更长,你将需要增加零和截断点的数量或进行测试):

按右排序(concat("0000000000", sortField), 10)

于 2013-06-08T00:12:02.717 回答
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
于 2013-06-07T16:20:00.507 回答
0

另一种方法是修剪和右对齐你的字符串。假设您的列宽 20 个字符。你可以使用类似的东西

right(repeat(' ',20)||trim(yourdata),20)

当然,如果字符串以非数字字符开头,这不会很好。

于 2013-06-08T00:08:17.527 回答