删除MySQL中字符串的垃圾部分

Delete garbage parts of strings in MySQL

提问人:Arash Rabiee 提问时间:6/25/2016 最后编辑:Arash Rabiee 更新时间:6/25/2016 访问量:198

问:

我的一个字段包含一个奇怪的文本部分,但其中有一些对我来说很重要: 例如:我的字段是这样的:

\“'Way Out\”(如何成为其中一人) (1961) {Side Show (#1.12)}\“'t Schaep Met De 5 Pooten\”

所有的文字都是垃圾,我只想要 1961 年。
此外,我的表有超过 200K 行。

年份在括号内。下面显示的查询适用于每个位置,但是当我在年份之前的括号内有一些东西时,就会出现问题。 所有的文字都是垃圾,但年份是必需的。我已经用过了:

UPDATE `myTable`
SET `myField` = (SUBSTRING_INDEX(`myField`, '(', -3));
UPDATE `myTable`
SET `myField` = (SUBSTRING_INDEX(`myField`, ')', 3));
UPDATE `myTable`
SET `myField` = (SUBSTRING_INDEX(`myField`, ')', 2));
UPDATE `myTable`
SET `myField` = (SUBSTRING_INDEX(`myField`, ')', 1));

有没有办法进行查询,仅将值保存在包含 4 位数字的任何括号内? 在上面的 ex 中,结果应该是:1961

MySQL的

评论

0赞 1000111 6/25/2016
是否可以在一列中包含多个 4 位字符串?
1赞 Arash Rabiee 6/25/2016
不,唯一的 4 位数字字符串是年份,每行都是 Uniqe
0赞 Rolf ツ 6/25/2016
谈谈糟糕的数据库设计...我不知道你是怎么得到这个数据库的,但我会先把它规范化。还可以提高查询性能。

答:

1赞 Bernd Buffen 6/25/2016 #1

如果 (xxxx) 中只有一个 4 位值,那么您可以使用REGEXP_REPLACE,但我不确定它是否仅在 MariaDB 中

SELECT
  REGEXP_REPLACE( 
    "Way Out\"(How to be one) (1961) {Side Show (#1.12)}\"'t Schaep Met De 5 Pooten"
    , '^(.*) \\(([0-9]{4})\\) (.*)$'
    , '\\2'
  ) AS VAL;

样本

MariaDB [yourSchema]> SELECT
    ->   REGEXP_REPLACE(
    ->     "Way Out\"(How to be one) (1961) {Side Show (#1.12)}\"'t Schaep Met De 5 Pooten"
    ->     , '^(.*) \\(([0-9]{4})\\) (.*)$'
    ->     , '\\2'
    ->   ) AS VAL;
+------+
| VAL  |
+------+
| 1961 |
+------+
1 row in set (0.00 sec)

MariaDB [yourSchema]>

评论

0赞 Arash Rabiee 6/25/2016
我尝试了您的解决方案,但我遇到以下错误:[Err] 1305 - FUNCTION product。REGEXP_REPLACE不存在
1赞 1000111 6/25/2016
MYSQL 不支持 .@ArashRabieeREGEXP_REPLACE
0赞 Bernd Buffen 6/25/2016
@Arash狂犬病 - 如果你只需要一次,你可以我发送一个zip SQL文件,我会在MariaDB中为你快速更改它。这不是您问题的解决方案
1赞 fthiella 6/25/2016 #2

如果字符串的结构是固定的,可以搜索右括号 ),然后搜索左括号(首先:

select substring_index(text, ') (', -1)

然后,您可以在第一个打开括号之前获取此子字符串的部分:

select
  substring_index(
    substring_index(text, ') (', -1),
    ')',
    1
  )

评论

0赞 Arash Rabiee 6/25/2016
不,牵引没有固定,唯一固定的部分是 pranthesis 内只有一个 4digits
2赞 1000111 6/25/2016 #3

你可以试一试(我想这是一次性工作,因此留下性能问题):

UPDATE myTable MT

CROSS JOIN 
(
    Select (th*1000+h*100+t*10+u+1) x from
    (select 0 th union select 1 union select 2 union select 3 union select 4 union
    select 5 union select 6 union select 7 union select 8 union select 9) A,
    (select 0 h union select 1 union select 2 union select 3 union select 4 union
    select 5 union select 6 union select 7 union select 8 union select 9) B,
    (select 0 t union select 1 union select 2 union select 3 union select 4 union
    select 5 union select 6 union select 7 union select 8 union select 9) C,
    (select 0 u union select 1 union select 2 union select 3 union select 4 union
    select 5 union select 6 union select 7 union select 8 union select 9) D
    WHERE (th*1000+h*100+t*10+u+1) >= 1800
    AND (th*1000+h*100+t*10+u+1) <= 3000
    order by x
) t
SET MT.myField = t.x
WHERE `myField` LIKE CONCAT('%',t.x,'%');

注意:假设您的年份字符串在此范围内:from 1800 to 3000

最好将最小和最大年份放在 where 子句中

WHERE (th*1000+h*100+t*10+u+1) >= MINIMUM_YEAR AND (th*1000+h*100+t*10+u+1) <= MAXIMUM_YEAR

在运行上述查询之前:

SQL FIDDLE 演示

运行上述查询后:

SQL FIDDLE

评论

0赞 Arash Rabiee 6/25/2016
它导致了以下错误:“[Err] 1205 - 超出锁定等待超时;尝试重新启动事务“,但是当我在大约 1000 行的小表中使用它时,它起作用了。但我的表有656024行
1赞 Arash Rabiee 6/25/2016
我重新启动了mysql服务并再次尝试了此命令,它运行良好
0赞 1000111 6/25/2016
可能是其他一些进程锁定了记录。显然,此更新在更新时将花费比平时更长的时间。这就是为什么我在回答中某处提到了性能问题这个词。顺便说一句,它对你有用,听起来很棒。
1赞 1000111 6/25/2016
谢谢@BerndBuffen。我以为我会因为这种方法而遇到反对票。