订购数据库中存储为字符串的数字

时间:2008-10-16 22:23:00

标签: database language-agnostic sql-order-by

我在数据库中的几个表中有一堆记录,这些表有一个“进程号”字段,基本上是一个数字,但我必须将它存储为字符串,因为有些遗留数据有“89a”之类的东西“作为一个数字和一些编号系统,要求将过程编号表示为数字/年。

当我尝试按编号订购流程时出现问题。我得到的东西是:

  • 1
  • 10
  • 11
  • 12

另一个问题是当我需要添加一个新进程时。新进程的编号应该是增加1的最大现有编号,为此我需要一种方法来按编号对现有记录进行排序。

有什么建议吗?

8 个答案:

答案 0 :(得分:1)

Maybe this will help.

本质:

SELECT process_order FROM your_table ORDER BY process_order + 0 ASC

答案 1 :(得分:1)

您可以将数字存储为零填充值吗?即,01,10,11,12?

答案 2 :(得分:1)

我建议创建一个仅用于排序的新数字字段,并从触发器更新它。

答案 3 :(得分:1)

您可以将数据拆分为两个字段吗?

将“流程编号”存储为int,将“流程子类型”存储为字符串。

那样:

  • 您可以轻松获取MAX processNumber - 并在需要生成时增加它 新号码
  • 你可以ORDER BY processNumber ASC, processSubtype ASC - 获取 正确的顺序,即使多个记录具有相同的基数,并附加不同的年/字母
  • 当你需要'完整'号码时 可以只连接两个字段

那会做你需要的吗?

答案 4 :(得分:1)

鉴于您的流程编号似乎没有遵循任何固定模式(来自您的问题和评论),您是否可以构建/维护一个包含两个字段的流程编号表:

create table process_ordering ( processNumber varchar(N), processOrder int )

然后从表中选择所有流程编号并插入流程编号表。根据(变化的)过程编号格式设置所需的排序。加入此表,按processOrder排序,然后从另一个表中选择所有字段。将此表索引在processNumber上以使连接快速。

select my_processes.*
from my_processes
  inner join process_ordering on my_process.processNumber = process_ordering.processNumber
order by process_ordering.processOrder

答案 5 :(得分:1)

在我看来,你在这里有两项任务。

•按照旧格式将字符串转换为数字/剥离垃圾
•订购数字

如果您有一种实用的方法可以将字符串解析正则表达式引入您的流程(并且您的问题有足够的数量值得付出努力),那么我会

•创建参考表,例如


CREATE TABLE tblLegacyFormatRegularExpressionMaster(
    LegacyFormatId int,
    LegacyFormatName varchar(50),
    RegularExpression varchar(max)
)

•然后,通过调用正则表达式的方式,例如SQL Server 2005及更高版本中的CLR集成(.NET公共语言运行时集成,允许从SQL Server中调用已编译的.NET方法普通(微软扩展)T-SQL ,那么你应该能够解决你的问题。

•见

http://www.codeproject.com/KB/string/SqlRegEx.aspx

我很抱歉,如果这对你手头的问题来说太过分了。

答案 6 :(得分:1)

建议:

•使您的专栏成为固定宽度的文字(即CHAR而不是VARCHAR)。

•使用足够的前导零填充现有值以填充每个列以及值不以“a”(或其他)结尾的尾随空格。 •添加CHECK约束(或等效约束)以确保新值符合模式,例如

之类的东西
CHECK (process_number LIKE '[0-9][0-9][0-9][0-9][0-9][0-9][ab ]')

•在插入/更新存储过程(或等效的)中,填充任何传入的值以适合模式。

•向人类显示值时,适当删除前导/尾随零/空格。

这种方法的另一个优点是输入值'1','01','001'等都被认为是相同的值,并且可以被DBMS中的简单唯一约束覆盖。

BTW我喜欢将尾随'a'(或其他)拆分成一个单独的列的想法,但我得到的印象是所讨论的数据元素是一个标识符,因此不适合拆分它。

答案 7 :(得分:0)

您需要在选择时投射您的字段。我将这种语法基于MySQL - 但这个想法是一样的:

select * from table order by cast(field AS UNSIGNED);

当然,如果需要,可以签署UNSIGNED。