【问题标题】:how can extract part of a text from a field in mysql?如何从mysql中的字段中提取部分文本?
【发布时间】:2014-10-22 16:47:08
【问题描述】:

我有这样的字段:

-----------------
   id    |  name  
-----------------
   1     |  name123  
-----------------
   2     |  name  
-----------------
   3     |  name456  
-----------------
   4     |  name  

我想提取名称中有数字的行和包含这样数字的字段

------------------------------
   id    |  name     | number
-----------------------------
   1     |  name123  |  123
-----------------------------
   3     |  name456  |  456

我们如何找到有数字的记录并将数字提取为新字段?

【问题讨论】:

  • 我假设名称可以是任意名称和任意长度,对吧?
  • 是的,名字长度不限!
  • 我认为这在 MySQL 中是不可能的。 .NET 控制台应用程序的代码,或者 PHP 或 C# 等基于 Web 的应用程序的代码会有帮助吗?
  • 我在 PHP 站点中使用它
  • 你必须在 MYSQL 查询中进行,还是可以在之后对数据进行微调? stackoverflow.com/questions/4311156/…

标签: mysql regex regexp-substr


【解决方案1】:

这是使用mysql的另一种方法

SELECT 
  id,
  name,
  SUBSTRING( 
    name,LEAST (
      if (Locate('0',name) >0,Locate('0',name),999),
      if (Locate('1',name) >0,Locate('1',name),999),
      if (Locate('2',name) >0,Locate('2',name),999),
      if (Locate('3',name) >0,Locate('3',name),999),
      if (Locate('4',name) >0,Locate('4',name),999),
      if (Locate('5',name) >0,Locate('5',name),999),
      if (Locate('6',name) >0,Locate('6',name),999),
      if (Locate('7',name) >0,Locate('7',name),999),
      if (Locate('8',name) >0,Locate('8',name),999),
      if (Locate('9',name) >0,Locate('9',name),999)
    ),LENGTH(name)
  ) as number
from users 
having number <> '' ;

【讨论】:

  • 我喜欢您在 SUBSTRING 上使用 LEAST 非常酷... +1 我...但现在 OP 说名称也可以以数字开头:/
  • @JohnRuddell 使用这种方法对特定模式有好处,但对于混合模式则不合适。但我喜欢你的 +1
  • +1 @Abhik Chakraborty 为您提供帮助。我学习了有关 SQL 的新知识
【解决方案2】:

你可以在一个 int 上使用 MySQL 的字符串转换来像这样去掉名字

SELECT 
    t.id, 
    t.name, 
    REVERSE(REVERSE(t.name)+ 0) AS num,
    REPLACE(t.name,REVERSE(REVERSE(t.name)+ 0),'') AS actualname
FROM foobar t
HAVING num <> 0

这个技巧是通过添加一个 0 mysql 比较名称中的数值...但是名称必须以数字开头...所以我反转它进行计算然后再次反转... 注意你所有的名字都必须以名字开头并以数字结尾,这样才能对所有人都有效

FIDDLE DEMO


编辑:

既然你说有些可以以数字开头,有些可以以数字结尾..那么试试这个

SELECT 
    t.id, 
    t.name, 
    REVERSE(REVERSE(t.name)+ 0) AS num,
    REPLACE(t.name,REVERSE(REVERSE(t.name)+ 0),'') AS actualname
FROM foobar t
HAVING num <> 0
UNION ALL
SELECT 
    t.id, 
    t.name, 
    t.name + 0 AS num,
    REPLACE(t.name,t.name + 0,'') AS actualname
FROM foobar t
HAVING num <> 0

ANOTHER DEMO

【讨论】:

  • 这看起来不错,但名称更复杂。可以以数字开头,也可以不以数字结尾。
  • @MAliFahimi 您可以使用替换运行此查询两次,一次不使用替换并将值存储在临时表中以将所有值连接在一起
  • @MAliFahimi 如果名称更复杂,那么为什么不提供正确的信息让我们写下查询?
  • 感谢大家,您的回答太棒了,但我认为最好在应用层中进行...+1 @John Ruddell
  • @MAliFahimi 在应用层做会更好。但是,您能否将其中一个答案标记为已接受以结束此问题?它对社区也更好:) 将不胜感激。
【解决方案3】:

另一种方式,假设您想要的数字在字符串的末尾。 REVERSE() 将数字部分放在前面,然后 CONVERT() 使其成为数字并剥离文本,然后 REVERSE() 再次 WHERE name 以数字结尾。不过感觉像个杂牌:

select id, name, reverse(convert(reverse(name),signed ))
from tbl
where name REGEXP '[0-9]+$';  

SQL Fiddle Example

【讨论】:

    猜你喜欢
    • 2015-11-17
    • 1970-01-01
    • 1970-01-01
    • 2017-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-12
    • 1970-01-01
    相关资源
    最近更新 更多