MAX(列名称)不会返回精确的最大值

时间:2015-06-27 15:14:24

标签: php sql

我的表test包含id列和code列。它看起来像这样:

id     code

1      AF1
2      AF5
3      AF6
4      AF9
5      AF45

要获得最大代码值,我尝试使用sql-instruction,如:

SELECT MAX(code) from test

但是,它并没有返回所需的结果。它返回AF9作为最大值。

现在,我的问题是:

  • 前缀AF是否导致问题?
  • 我应该如何获得理想的结果?

2 个答案:

答案 0 :(得分:2)

AR9 的最大值。比较是字符串。

如果要将字符串的一部分作为数字进行比较,则需要转换它们。

一种方法是使用substring()cast()

order by substring(code, 1, 2),
         cast(substring(3, 10) as int)

或者,如果没有填充数字,则使用字符串长度有一个技巧:

order by length(code), code

注意:字符串长度和子字符串操作的函数因数据库而异,因此确切的函数可能会有所不同,具体取决于您使用的系统。

答案 1 :(得分:1)

MySQL中没有自然排序顺序。在狡猾的查询之外,有几种方法可以解决这个问题。 (当索引不能用于排序顺序时,狡猾的查询会变得昂贵。)

  • 如果您的所有前缀都是AF,那么您最好删除前缀并简单地存储整数。
  • 如果您有其他前缀,请使用单独的列来存储字符串和整数部分。
  • 用零填充代码的数字部分;即。 AF0045并保持字符串。您无法在字符串上使用MAX(),但始终可以ORDER BY code DESC LIMIT 1。这显然性能更昂贵,但仍然可能比使用子串等便宜。

如果您只想删除AF前缀,可以执行UPDATE test SET code = replace(code, 'AF', ''),然后将列转换为整数。如果您只是使用当前代码格式将列转换为整数,那么它将满零并且您当前的数据将会丢失。

如果某个代码是45AF,那么它会变成" 45",但由于前导的非数字部分,AF45转换为整数会返回0 。如果您的MySQL设置为严格,则会收到有关截断数据的错误。因此,在色谱柱转换之前进行清理是一种很好的做法。

如果您有多个前缀,则需要单独存储,然后使用Gordon的答案中的子字符串和强制转换方法UPDATE ... SELECT ,像这样(在创建额外的列之后):

UPDATE test SET 
code_prefix = SUBSTRING(code, 1, 2), 
code_number = CAST(SUBSTRING(code, 3, 10) AS INT);

根据您的源代码格式对您的结构进行规范化,将原始代码的部分内容存储在单独的字符串和整数列中 - 您可以在整数上使用MAX(code_number)