简体   繁体   English

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

[英]MySQL find and update based on results from 2 tables

First off, please note that this is not answered in the question here: MySQL update table based on another tables value or indeed any other Stack question or answer that I could find!首先,请注意这里的问题没有回答: 基于另一个表值的 MySQL 更新表或我能找到的任何其他堆栈问题或答案!

I converted a forum on a website and now just need to repair the internal URL links on a few hundred of the posts.我在网站上转换了一个论坛,现在只需要修复几百个帖子的内部 URL 链接。

Posts are found in the column post_content within the table xyz_posts帖子位于表xyz_posts 的post_content列中

ID     post_content  

1467  This is great https://example.com/index.php?topic=1234 I really like it
1468  Hello world
1469  Take a look https://example.com/index.php?topic=5678.0

You can see the URLs are mostly buried in the post text.您可以看到 URL 大部分都隐藏在帖子文本中。 Note that the example above can sometimes be written with topic=1234.0 at the end, although it is actually stored in the database as a value of 1234. I don't want to rewrite the url and accidentally keep the .0注意上面的例子有时可以写成topic=1234.0结尾,虽然它实际上是作为值1234存储在数据库中的。我不想重写url,不小心保留了.0

Here's an example of how I need that table to look:这是我需要该表的外观示例:

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/

So, the table xyz_converter maps the old topic number to the new post ID like this:因此,表xyz_converter将旧主题编号映射到新帖子 ID,如下所示:

meta_key             meta_value     value_id  

_bbp_old_topic_id    1234           15675
_bbp_old_reply_id    1234           17439

Caveat here, the number 1234 also exists in this table for forum replies which we don't want, but the meta_key and value_id are different for those as shown.此处需要注意的是,此表中也存在数字 1234 用于我们不想要的论坛回复,但如图所示,meta_key 和 value_id 是不同的。 This SQL query works to get to the right one:此 SQL 查询可以找到正确的查询:

SELECT * FROM `xyz_converter` WHERE meta_key LIKE '_bbp_old_topic_id' AND `meta_value` LIKE '1234'

Also in table xyz_posts we map the value_id mentioned above to the post's URL suffix like this:同样在表xyz_posts 中,我们将上面提到的value_id映射到帖子的 URL 后缀,如下所示:

ID        post_name

15675     finished-page 
15676     another-page 

How do I construct a SQL query that will detect the meta_value in one table and then replace it with the correct final URL as mentioned?如何构建一个 SQL 查询来检测一个表中的 meta_value,然后将其替换为提到的正确最终 URL?

PROCESS SUMMARY过程总结

  1. Detect the URL in xyz_posts post_content检测xyz_posts post_content 中的 URL
  2. Extract the topic number from the URL (eg 1234).从 URL 中提取主题编号(例如 1234)。 If it's 1234.0 then take just 1234如果是 1234.0,则只需 1234
  3. Convert it to a post number in found in xyz_converter value_id (eg 15675) ensuring it is found alongside _bbp_old_topic_id将其转换为在xyz_converter value_id 中找到的帖子编号(例如 15675),确保它与 _bbp_old_topic_id 一起找到
  4. Take the suffix of the URL in xyz_posts post_name (eg 'finished-page')xyz_posts post_name 中 URL 的后缀(例如'finished-page')
  5. Rewrite the original URL to include the suffix (not forgetting the trailing slashes).重写原始 URL 以包含后缀(不要忘记尾部斜杠)。

I'm using MySQL 5.7.29 and PHPMyAdmin .我正在使用MySQL 5.7.29PHPMyAdmin I'm fairly new to SQL queries and a Regex noob, but willing to learn more!我对 SQL 查询和正则表达式菜鸟相当陌生,但愿意了解更多!

A solution that uses only MySQL commands and works in MySQL 5.7 could be like this.仅使用 MySQL 命令并在 MySQL 5.7 中工作的解决方案可能是这样的。

If .0 is present only in the urls you could use a query like this to remove all occurences of .0 from post_content in xyz_posts .如果.0仅存在于 url 中,您可以使用这样的查询从xyz_posts post_content中删除所有出现的.0

UPDATE `xyz_posts` SET post_content=REPLACE(post_content,'.0 ',' ') WHERE post_content LIKE '%topic=%.0 %';

Then you can use然后你可以使用

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);

The first command will create a temporary table where the first column will be the value that you want to find and replace like index.php?topic=1234 and the second column will be the value you want to be replace with like finished-page第一个命令将创建一个临时表,其中第一列将是您要查找和替换的值,例如index.php?topic=1234 ,第二列将是您要替换的值,例如finished-page

The second command will replace posts_content in xyz_posts taking the first column from temp_tbl and replacing it with the second column.第二个命令将替换posts_content中的xyz_poststemp_tbl获取第一列并将其替换为第二列。

Below an sql fiddle where you can see the solution in action在 sql fiddle 下方,您可以在其中看到实际中的解决方案

http://sqlfiddle.com/#!9/7bce8c http://sqlfiddle.com/#!9/7bce8c

Of course you should first create a copy of your database and try these commands to ensure everything works fine before trying it in your production database.当然,在您的生产数据库中尝试之前,您应该首先创建数据库的副本并尝试这些命令以确保一切正常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM