13

我想从表的字符串列中提取一个单词。

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

我正在使用 LOCATE 和 SUBSTR 来解决问题。代码很丑。写完代码十分钟后,我在诅咒写这么丑代码的家伙。

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

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

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

4

4 回答 4

10

就像 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

编辑:您可以尝试这个用户定义的函数,提供对 MySql 中 perl 正则表达式的访问

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
于 2010-04-30T06:45:40.903 回答
10

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

是的,从 MySQL 8.0 开始支持它。正则表达式

REGEXP_SUBSTR(expr, pat[, pos[, occurrence[, match_type]]])

返回与模式 pat 指定的正则表达式匹配的字符串 expr 的子字符串,如果没有匹配则返回 NULL。如果 expr 或 pat 为 NULL,则返回值为 NULL。

于 2018-04-19T19:38:00.630 回答
5

或者您可以这样做并避免丑陋:

select SUBSTRING_INDEX(SUBSTRING_INDEX('habc order_id: 2 xxxx yyy aa',' ',3),' ',-1);
于 2016-11-20T19:00:32.360 回答
1

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

您可以尝试使用存储过程和大量 REPLACE/SUBSTRING 逻辑,也可以使用您的编程语言进行操作——这应该是最简单的选择。

但是您确定您的数据格式选择得当吗?如果您需要 order_id,将其存储在不同的列中是否有意义,以便您可以放置​​索引、使用连接等?

于 2010-04-30T06:35:04.850 回答