【问题标题】:Convert partially non-numeric text into number in MySQL query在 MySQL 查询中将部分非数字文本转换为数字
【发布时间】:2011-08-23 01:39:30
【问题描述】:

是否可以在 MySQL 查询中将文本转换为数字?我有一个带有标识符的列,其中包含一个名称和一个“名称-编号”格式的数字。该列具有 VARCHAR 类型。我想根据数字(具有相同名称的行)对行进行排序,但列是根据字符顺序排序的,即

name-1
name-11
name-12
name-2

如果我切断数字,我可以将“varchar”数字转换为“真实”数字并使用它对行进行排序吗?我想获得以下订单。

name-1
name-2
name-11
name-12

我不能将数字表示为单独的列。

于 2011-05-11 9:32 编辑

我找到了以下解决方案... ORDER BY column * 1。如果名称不包含任何数字,使用该解决方案是否安全?

【问题讨论】:

  • name 正是 name 或者它可以是任何字符?我的意思是:它是一个四个字符长的字符串还是一个真实姓名?
  • name 可以是任意字母序列。
  • mysql natural sorting 的可能重复项

标签: mysql sql


【解决方案1】:

您可以使用CAST() 将字符串转换为整数。例如SELECT CAST('123' AS INTEGER);

【讨论】:

  • 那个版本是特定的吗?我需要使用SELECT CAST('123' AS SIGNED INTEGER);SELECT CAST('123' AS UNSIGNED INTEGER); 才能让它工作。
【解决方案2】:

要获取号码,请尝试使用SUBSTRING_INDEX(field, '-', 1) 然后进行转换。

【讨论】:

【解决方案3】:

您可以使用SUBSTRINGCONVERT

SELECT stuff
FROM table
WHERE conditions
ORDER BY CONVERT(SUBSTRING(name_column, 6), SIGNED INTEGER);

其中name_column 是具有“name-”值的列。 SUBSTRING 删除第六个字符之前的所有内容(即“name-”前缀),然后 CONVERT 将剩下的转换为实整数。

更新:鉴于 cmets 中不断变化的情况(即前缀可以是任何东西),您必须在组合中添加 LOCATE

ORDER BY CONVERT(SUBSTRING(name_column, LOCATE('-', name_column) + 1), SIGNED INTEGER);

这当然假设非数字前缀没有任何连字符,但相关评论说:

name 可以是任意字母序列

所以这应该是一个安全的假设。

【讨论】:

  • 回答我的评论时,他告诉我们 name 可以是任何字符序列,所以我不确定你是否可以使用 SUBSTRING(name_column, 6)。我知道,你在他没有告诉我们的时候发布了它......
  • @Marco:感谢您的提醒,我添加了一个更新,应该处理有关前缀的新信息。但是,是的,您的 SUBSTRING_INDEX 更好。
【解决方案4】:

这应该可行:

SELECT field,CONVERT(SUBSTRING_INDEX(field,'-',-1),UNSIGNED INTEGER) AS num
FROM table
ORDER BY num;

【讨论】:

  • 能否添加说明和文档链接?
  • 我的字符串就像“name-abc12”。通过添加您的代码,它仅在“-”之后的初始字符不以字母开头时才有效。 @Marco 你能告诉我一种在没有 where 条件的情况下忽略字母的方法吗?
  • @Eduardo 我的查询应该获取“-”之后的字符串并将其转换为数字(它必须是数字)。在你的情况下,我可能会继续使用正则表达式......
  • @Marco 正则表达式做到了,谢谢你的提示。
  • More info 在这个命令上
【解决方案5】:
SELECT *, CAST(SUBSTRING_INDEX(field, '-', -1) AS UNSIGNED) as num FROM tableName ORDER BY num;

【讨论】:

  • 您确定 ORDER BY 使用 num 作为数字而不使用 CONVERT?我不确定,但它可以是..我只是在问自己:)
【解决方案6】:

如果你的主键是一个字符串,格式如下

ABC/EFG/EE/13/123(序号)
这种字符串可以很容易地使用分隔符(“/”)进行排序

我们可以使用下面的查询来对具有这种类型键的表进行排序

SELECT * FROM `TABLE_NAME` ORDER BY 
CONVERT(REVERSE(SUBSTRING(REVERSE(`key_column_name`), 1, LOCATE('/', REVERSE(`key_column_name`)) - 1)) , UNSIGNED INTEGER) DESC

【讨论】:

    【解决方案7】:

    一种简单的方法 SELECT '123'+ 0

    【讨论】:

    • 虽然此代码可能有助于解决问题,但提供有关 why 和/或 如何 回答问题的附加上下文将显着改善其长期价值。请edit你的答案添加一些解释。
    • 这没有回答问题,但这是我正在寻找的答案。
    • 您的解决方案是最优雅和实用的 - 不幸的是,您没有在问题的上下文中提供给定示例的具体表达方式 - 请修改为具体。
    【解决方案8】:

    只需使用 CAST,

    CAST(column_name AS UNSIGNED)
    

    转换结果的类型可以是以下值之一:

    BINARY[(N)]
    CHAR[(N)]
    DATE
    DATETIME
    DECIMAL[(M[,D])]
    SIGNED [INTEGER]
    TIME
    UNSIGNED [INTEGER]
    

    【讨论】:

      【解决方案9】:

      一种通用的方法:

      SELECT * FROM your_table ORDER BY LENTH(your_column) ASC, your_column ASC
      

      【讨论】:

        【解决方案10】:
        cast(REGEXP_REPLACE(NameNumber, '[^0-9]', '') as UNSIGNED)
        

        【讨论】:

        • 正是我想要的:)
        • 这是我的幸运,我出来帮了你。
        【解决方案11】:
        select
            `a`.uuid,
            concat('1',REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(`a`.uuid,'-',''),'b','11'),'c','12'),'d','13'),'e','14'),'f','15'),'a','10')),
        

        【讨论】:

        • 请在您的答案中添加一些解释,以便其他人可以从中学习
        • 这个可能只是在响应这篇文章的标题——将文本转换为数字(在本例中为文本 uuid 字符串)——使用替换(或几乎任何其他东西)通常比正则表达式。这也暗示了使用 uuid 字符串作为主键的想法。如果这是本例中的目标,则普通的旧自动增量或二进制 uuid 将比转换为字符串更快。
        【解决方案12】:

        我发现使用 regex_replace 函数从字段中删除所有非数值然后排序更容易。

        SELECT field , CONVERT(REGEXP_REPLACE(field,'[^0-9]',''),UNSIGNED) AS num FROM your_table ORDER BY num;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-03-08
          • 1970-01-01
          • 1970-01-01
          • 2021-06-14
          • 1970-01-01
          • 2013-05-02
          • 1970-01-01
          相关资源
          最近更新 更多