2010-04-30 192 views
8

我想从表格的字符串列中提取单词。mysql中的REGEXP_SUBSTR等价于什么?

description 
=========================== 
abc order_id: 2 xxxx yyy aa 
mmm order_id: 3 nn kk yw 

预期的结果集

order_id 
=========================== 
2 
3 

表将至多有100行,文本长度为〜256炭和柱总是具有一个order_id本。所以表现不是问题。

在Oracle中,我可以使用REGEXP_SUBSTR来解决这个问题。我将如何在MySQL中解决这个问题?

编辑1

我使用的定位和SUBSTR来解决这个问题。代码很丑陋。编写代码十分钟后,我诅咒编写这样一个丑陋代码的人。

我没有在MySQL文档中找到REGEXP_SUBSTR函数。但我希望它存在..

回答:为什么不能优化表?为什么数据以这种愚蠢的方式存储?

我给出的例子只是表示我正试图解决的问题。在真实场景中,我使用基于数据库的第三方排队软件来执行异步任务。队列将Ruby对象作为文本序列化。我无法控制表格结构或数据格式。队列中的任务可以重复发生。在我们的测试设置中,一些重复性任务由于陈旧的数据而失败。我必须删除这些任务以防止出现错误。这样的错误并不常见,因此我不想维护标准化的影子表。

回答

3

就像Konerak说的那样,在MySql中没有等价的REGEXP_SUBSTR。你可以做你需要使用SUBSTRING逻辑的,但它是丑陋:

SELECT 
    SUBSTRING(lastPart.end, 1, LOCATE(' ', lastPart.end) - 1) AS orderId 
FROM 
    (
    SELECT 
     SUBSTRING(dataset.description, LOCATE('order_id: ', dataset.description) + LENGTH('order_id: ')) AS end 
    FROM 
     (
     SELECT 'abc order_id: 2 xxxx yyy aa' AS description 
     UNION SELECT 'mmm order_id: 3 nn kk yw' AS description 
     UNION SELECT 'mmm order_id: 1523 nn kk yw' AS description 
    ) AS dataset 
    ) AS lastPart 

编辑:你可以试试这个user defined function提供访问perl的正则表达式在MySQL

SELECT 
    PREG_CAPTURE('/.*order_id:\s(\d+).*/', dataset.description,1) 
FROM 
    (
    SELECT 'abc order_id: 2 xxxx yyy aa' AS description 
    UNION SELECT 'mmm order_id: 3 nn kk yw' AS description 
    UNION SELECT 'mmm order_id: 1523 nn kk yw' AS description 
) AS dataset 
+1

这就是我正在做的。 +1为花时间写这个.. – 2010-04-30 07:06:33

+1

编辑答案使用CHAR_LENGTH()而不是LENGTH(),后者是以字节返回占用的大小,而不是字符串的长度。例如,你会遇​​到UTF8的麻烦 – 2013-06-14 05:50:11

1

没有MySQL的等价物。 MySQL REGEXP可用于匹配字符串,但不能用于转换它们。

您可以尝试使用存储过程和大量的REPLACE/SUBSTRING逻辑,或者使用您的编程语言 - 这应该是最简单的选择。

但是你确定你的数据格式是精心挑选的吗?如果您需要order_id,将它存储在不同的列中是否有意义,因此您可以放置​​索引,使用连接等?

+1

我们不能总是选择我们数据格式。例如,在进行数据迁移或从其他系统导入数据时,我们经常需要处理任何我们提供的内容。 – APC 2010-04-30 06:42:33

+0

阅读我更新的问题,为什么我有这样的数据。 – 2010-04-30 07:07:02

0

,或者你可以做到这一点,并节省自己的丑:

select SUBSTRING_INDEX(SUBSTRING_INDEX('habc order_id: 2 xxxx yyy aa',' ',3),' ',-1);