MySQL根据两个表的结果查找和更新

MySQL根据两个表的结果查找和更新,mysql,regex,Mysql,Regex,首先,请注意,这里的问题没有回答这个问题: 或者我能找到的任何其他问题或答案 我在一个网站上转换了一个论坛,现在只需要修复几百篇帖子上的内部URL链接 帖子可在表xyz_Posts中的post_content列中找到 您可以看到URL大部分隐藏在post文本中。 请注意,上面的示例有时可以使用topic=1234.0作为结尾编写,尽管它实际上是以1234的值存储在数据库中的。我不想重写url并意外地保留.0 下面是一个我需要该表的外观示例: ID post_content 1467

首先,请注意,这里的问题没有回答这个问题: 或者我能找到的任何其他问题或答案

我在一个网站上转换了一个论坛,现在只需要修复几百篇帖子上的内部URL链接

帖子可在表xyz_Posts中的post_content列中找到

您可以看到URL大部分隐藏在post文本中。 请注意,上面的示例有时可以使用topic=1234.0作为结尾编写,尽管它实际上是以1234的值存储在数据库中的。我不想重写url并意外地保留.0

下面是一个我需要该表的外观示例:

ID     post_content  

1467  This is great https://example.com/finished-page/ I really like it
1468  Hello world
1469  Take a look https://example.com/another-page/
因此,表xyz_converter将旧的主题号映射到新的帖子ID,如下所示:

meta_key             meta_value     value_id  

_bbp_old_topic_id    1234           15675
_bbp_old_reply_id    1234           17439

这里需要注意的是,对于我们不想要的论坛回复,数字1234也存在于这个表中,但是meta_键和value_id与所示的不同。此SQL查询用于找到正确的查询:

SELECT * FROM `xyz_converter` WHERE meta_key LIKE '_bbp_old_topic_id' AND `meta_value` LIKE '1234'
同样在表xyz_posts中,我们将上面提到的值_id映射到post的URL后缀,如下所示:

ID        post_name

15675     finished-page 
15676     another-page 
如何构造一个SQL查询来检测一个表中的meta_值,然后用前面提到的正确的最终URL替换它

过程总结

检测xyz_posts_内容中的URL 从URL中提取主题号,例如1234。如果是1234.0,则只需1234 将其转换为xyz_converter value_id如15675中的帖子编号,确保它与_bbp_old_topic_id一起找到 在xyz_posts_name中使用URL的后缀,例如“finished page” 重写原始URL以包含后缀,但不要忘记后面的斜杠。 我正在使用MySQL 5.7.29和PHPMyAdmin。
我对SQL查询和RegexNoob相当陌生,但愿意了解更多

一个只使用MySQL命令并在MySQL 5.7中运行的解决方案可能是这样的

如果.0仅存在于URL中,则可以使用类似这样的查询从xyz_帖子的帖子内容中删除所有出现的.0

然后你可以用

CREATE TABLE temp_tbl
SELECT CONCAT('index.php?topic=',c.meta_value) as `find_value` ,p.post_name as `replace_value`
FROM `xyz_converter` c
INNER JOIN `xyz_posts` p ON c.value_id=p.id AND `meta_key`='_bbp_old_topic_id'
ORDER BY meta_value DESC;

UPDATE `xyz_posts` p 
INNER JOIN  `temp_tbl` t ON p.post_content LIKE CONCAT('%',t.find_value,'%')
SET p.`post_content`=REPLACE(p.`post_content`,t.find_value,t.replace_value);
第一个命令将创建一个临时表,其中第一列是要查找并替换的值,如index.php?topic=1234,第二列是要替换为类似完成页面的值

第二个命令将替换xyz_posts中的posts_内容,从temp_tbl获取第一列并将其替换为第二列

下面是一个sql FIDLE,您可以在其中看到正在运行的解决方案


当然,在生产数据库中尝试之前,您应该首先创建数据库的副本,并尝试这些命令以确保一切正常。

mysql 5.7没有太多的regexp功能,但您可以备份到mysql 8并在那里进行更改。在5.7 A中导入表,然后更新原始表。剩下的9o不明白你在找什么。@Sara44我回答了你的问题,但不清楚你想要什么。你想更新xyz_转换器或xyz_帖子吗?@GeorgePant请看我对你答案的答复。我重新构造了这个问题。@Sara44我也重新构造了我的答案:pSome在SQL中不实用。用PHP或任何应用程序语言完成任务;这里会容易得多。感谢@George Pant的回复,但我需要替换表xyz_posts中的post_内容列中的URL字符串,而不是更改任何其他表数据。这篇文章并没有从表中提取原始的URL,它们是用户生成的内部链接。编辑它们是为了进一步澄清问题。不幸的是,并非所有数据都在xyz_帖子中。在返回获取postname之前,我们必须查询xyz_转换器以获得正确的映射。我设法消除了所有.0引用。我尝试了temp表代码的第一部分,包括第一个内部连接行,只是想看看它是否会创建表,它说MySQL返回了一个空的结果集,即零行。我的语法看起来不错,有什么想法吗?我会坚持下去,非常感谢迄今为止的帮助。有时需要几天才能回复你,但我会的!顺便说一句,我需要最后URL的尾随斜杠。@Sara44 CREATE TEMPORARY TABLE只创建一个只存在于该会话中的临时表。因此,您执行的每个其他查询都必须在phpmyadmin中的同一会话中,您必须在同一窗口中复制粘贴所有命令。或者,你可以使用关键字TEMPORARY创建一个普通的表,然后在创建完成后删除它。我最终成功地运行了这个表,但post_内容中的行数超过8000行,这需要一个小时才能完成,服务器在途中崩溃。还有一些格式错误的URL,我需要进行调查。是否有一种更有效的方法可以一次替换x行数?
UPDATE `xyz_posts` SET post_content=REPLACE(post_content,'.0 ',' ') WHERE post_content LIKE '%topic=%.0 %';
CREATE TABLE temp_tbl
SELECT CONCAT('index.php?topic=',c.meta_value) as `find_value` ,p.post_name as `replace_value`
FROM `xyz_converter` c
INNER JOIN `xyz_posts` p ON c.value_id=p.id AND `meta_key`='_bbp_old_topic_id'
ORDER BY meta_value DESC;

UPDATE `xyz_posts` p 
INNER JOIN  `temp_tbl` t ON p.post_content LIKE CONCAT('%',t.find_value,'%')
SET p.`post_content`=REPLACE(p.`post_content`,t.find_value,t.replace_value);