某些产品序列号的类型为varchar,并且字母表示类型后跟数字。这些数字是0填充最多5位数,我们接近'A100000'。
对于少于100000个项目的字母,他们仍然希望0个填充最多5个数字,并且那些字母数量超过100000的数字可以增加到任何数字。
它当前发现当前的最大序列号是这样的:
SELECT MAX(SerialNumber) FROM Table WHERE LEFT(SerialNumber, 1) = @leadingChar
但是,使用此方法'A99999'的选择超过'A100000',因为9> 1。 (同样的原因,动物园在苹果公司的字典中,更多的字符,但在领先的字符中价值较低。)
所以问题是,当每次获得新的序列号时,它会增加当前的最大序列号以获得“A99999”之后的下一个序列号,您将获得“A100000”。
将它们拆分为数据库中的char列和int列会很麻烦,因为它在几个表中使用,并且总序列号有几百万。
它是作为Web应用程序编写的,在vbscript / classic asp数据库中是SQL Server 7。
如果有更好的标签/标题随时可以编辑/让我知道。
感谢您的帮助。
答案 0 :(得分:4)
您可以考虑采用Matt Gibson在Coding Horror posting关于自然排序顺序的评论中描述的方法。
作为数据仓库开发人员,我不是 商人的方式比较陌生 期待看到事情排序,而且是 从来没有ASCII ...我做的一件事就是 在我的数据库中添加额外的列 放入“更正”的版本 我正在使用的钥匙,所以我的桌子可能看起来 像:
Customer Number|Customer|SortKey1 MS948|Fred Smith|MS00000948 MS9215|John Star|MS00009215
..这意味着我可以使用SQL 标准ASCII排序(索引为 速度,如果需要)而不是渣土 在客户端的任何东西 应用。客户介绍 对用户来说真正的关键,但是要按用户排序 预先计算的ASCII排序安全密钥, 而我只需要努力工作 一次,在前面。
这意味着在当前表中添加一个额外的字段,该字段仅用于密钥生成。 “获取下一个密钥”代码将引用新字段,但也会填充现有字段,以便大多数代码和外键数据可以保持原样。
如果SerialNumber字段上有索引,您还可以考虑使用SQL LIKE运算符来查找MAX。您发布的代码可能无法使用索引,因为您正在将函数应用于WHERE子句中的字段(我不熟悉SQL Server 7查询优化的详细信息,所以不能肯定地说)
答案 1 :(得分:3)
你可以尝试这个来获得主角的最大数字:
SELECT MAX(CAST(SUBSTRING(SerialNumber, 2, 99) AS INT))
FROM Table1
WHERE LEFT(SerialNumber, 1) = @leadingChar
虽然它将无法使用索引来查找最大数量,但速度会很慢。如你在问题中提到的那样,将它分成两列会更好。做出改变可能很尴尬,但它将在未来帮助你。
答案 2 :(得分:2)
如果您发现您的解决方案效率不高,并且您想要一个需要最少应用程序更改的更快的解决方案,那么您可以尝试这样做:
在表格中SerialLetter
和SerialNumber
创建两列。
然后像这样填充它们:
UPDATE Table SET
SerialLetter = SUBSTRING(Serial, 0, 1),
SerialNumber = SUBSTRING(Serial, 1, 99)
如果您的表很大,这些可能是一些非常长时间运行的查询,因此您可能希望在负载较低时执行此操作,并且您可能需要调整超时值。
然后创建更新并插入触发器,以便表中的任何序列都将反映在新列中。
然后按顺序在SerialLetter和SerialNumber上创建索引。 (两列上的一个索引)
然后你可以
SELECT MAX(SerialNumber) WHERE SerialLetter = 'X'
在很短的时间内,因为它只会使用索引,而且从不打击表。