我想从表格的字符串列中提取一个单词。
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函数。但我希望它存在..
答案:为什么不能优化表格?为什么数据以这种愚蠢的方式存储?
我给出的例子只是表示我想解决的问题。在实际情况中,我使用基于数据库的第三方排队软件来执行异步任务。队列将Ruby对象序列化为文本。我无法控制表结构或数据格式。队列中的任务可以重复出现。在我们的测试设置中,由于过时的数据,一些重复的任务失败了。我必须删除这些任务以防止错误。这些错误并不常见,因此我不想维护规范化的影子表。
答案 0 :(得分:5)
就像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访问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
答案 1 :(得分:3)
“我在MySQL文档中找不到 REGEXP_SUBSTR 函数。但我希望它存在..”
是的,从MySQL 8.0开始支持它。 Regular Expressions:
REGEXP_SUBSTR(expr, pat[, pos[, occurrence[, match_type]]])
返回与模式pat指定的正则表达式匹配的字符串expr的子字符串,如果没有匹配则返回NULL。如果expr或pat为NULL,则返回值为NULL。
答案 2 :(得分:1)
没有MySQL等价物。 MySQL REGEXP可用于匹配字符串,但不能用于转换它们。
您可以尝试使用存储过程和大量REPLACE / SUBSTRING逻辑,也可以使用您的编程语言 - 这应该是最简单的选择。
但您确定您的数据格式选择得当吗?如果你需要order_id,将它存储在不同的列中是不是有意义,所以你可以放索引,使用连接等?
答案 3 :(得分:1)
或者你可以做到这一点并保存自己的丑陋:
select SUBSTRING_INDEX(SUBSTRING_INDEX('habc order_id: 2 xxxx yyy aa',' ',3),' ',-1);