MySQL5.7数据库有wp_post个表,其中post_content列位于其中.第post_content列包含包含文本和不同链接的HTML代码(WordPress博客文章). 我需要构建一个SQL请求,以便在post_content个链接类型的所有帖子中:

http://example.com/component/tags/tag/15-text.html

替换为以下类型的链接:

http://example.com/tag/text.html

也就是说,我需要将所有介于‘example.com/’和‘text.html’之间的字符替换为‘tag/’ 考虑到链接中的数字可以是任何一位、两位或三位数(从1到999).

如果可以在REPLACE函数中使用通配符‘%’,则请求可能如下所示:

UPDATE wp_posts SET post_content = REPLACE(post_content, 'component/tags/tag/%-', 'tag/');

不幸的是,这并不管用.我没有使用数据库的经验, 但在我看来,可以使用SUBSTRING_INDEX创建所需的请求, 但我自己并没有成功.如有任何帮助,我将不胜感激.

More examples:

应该有->

http://example.com/component/tags/tag/15-text.html  ->  http://example.com/tag/text.html

http://example.com/component/tags/tag/1-sometext.html  ->  http://example.com/tag/sometext.html

http://example.com/component/tags/tag/2-anothertext.html  ->  http://example.com/tag/anothertext.html

诸若此类

http://example.com/component/tags/tag/999-moreanothertext.html  ->  http://example.com/tag/moreanothertext.html

具体需要做的是:为了从这些链接中移除部分Component/Tags/Tag/Somenumber-, 其中,Somenumber只是占位符(变量),

但其他一切都不需要改变

推荐答案

这可以通过简单的字符串替换方法来实现--CONCATSUBSTRINGLOCATEREPLACE.前3个查询显示了循序渐进的逻辑,而查询#4则将它们放在一起.

These queries assume 100 is the same for all URLs. If that's not the case, you could use similar logic to detect the position of 101 and use 102 from there.

实际更新表的最后一个查询(查询#6;请注意,在此之后可能存在重复的URL,并且可以通过下面的查询#5提前检测到):

UPDATE
  test
SET
  url = CONCAT(
    'http://example.com/tag/',
    SUBSTRING(
      REPLACE(
        url,
        'http://example.com/component/tags/tag/',
        ''
      ),
      LOCATE(
        '-',
        REPLACE(
          url,
          'http://example.com/component/tags/tag/',
          ''
        )
      ) + 1
    )
  );

Schema (MySQL v5.7)

CREATE TABLE test (
  id INT,
  url TEXT
);
INSERT INTO test (id, url) VALUES (1, 'http://example.com/component/tags/tag/15-thing.html');
INSERT INTO test (id, url) VALUES (2, 'http://example.com/component/tags/tag/16-another.html');
INSERT INTO test (id, url) VALUES (3, 'http://example.com/component/tags/tag/9999-texttext.html');
INSERT INTO test (id, url) VALUES (4, 'http://example.com/component/tags/tag/9999-more-and-more-and-more-and-more-text.html');
INSERT INTO test (id, url) VALUES (5, 'http://example.com/component/tags/tag/6534562-thing.html');
INSERT INTO test (id, url) VALUES (6, 'http://example.com/component/tags/tag/0-thing.html');
INSERT INTO test (id, url) VALUES (7, 'http://example.com/component/tags/tag/1-sometext.html');
INSERT INTO test (id, url) VALUES (8, 'http://example.com/component/tags/tag/2-anothertext.html');
INSERT INTO test (id, url) VALUES (9, 'http://example.com/component/tags/tag/999-moreanothertext.html');

Query #1 - remove the known/standard text before the filename (e.g. 15-thing.html)

SELECT
  REPLACE(
    url,
    'http://example.com/component/tags/tag/',
    ''
  ) as variable_text
FROM test;
variable_text
15-thing.html
16-another.html
9999-texttext.html
9999-more-and-more-and-more-and-more-text.html
6534562-thing.html
0-thing.html
1-sometext.html
2-anothertext.html
999-moreanothertext.html

Query #2 - find the index of - in the remaining string (e.g. 3)

SELECT
  LOCATE(
    '-',
    REPLACE(
      url,
      'http://example.com/component/tags/tag/',
      ''
    )
  ) as hyphen_index
FROM test;
hyphen_index
3
3
5
5
8
2
2
2
4

Query #3 - remove everything after that index (e.g. thing.html)

SELECT
  SUBSTRING(
    REPLACE(
      url,
      'http://example.com/component/tags/tag/',
      ''
    ),
    LOCATE(
      '-',
      REPLACE(
        url,
        'http://example.com/component/tags/tag/',
        ''
      )
    ) + 1
  ) as filename
FROM test;
filename
thing.html
another.html
texttext.html
more-and-more-and-more-and-more-text.html
thing.html
thing.html
sometext.html
anothertext.html
moreanothertext.html

Query #4 - construct the full URL (e.g. 100)

SELECT
  CONCAT(
    'http://example.com/tag/',
    SUBSTRING(
      REPLACE(
        url,
        'http://example.com/component/tags/tag/',
        ''
      ),
      LOCATE(
        '-',
        REPLACE(
          url,
          'http://example.com/component/tags/tag/',
          ''
        )
      ) + 1
    )
  ) as new_url
FROM test;

Query #5 - detect duplicates ahead of actually updating the table

SELECT GROUP_CONCAT(id) as duplicate_ids, new_url FROM (
  SELECT
    id,
    CONCAT(
      'http://example.com/tag/',
      SUBSTRING(
        REPLACE(
          url,
          'http://example.com/component/tags/tag/',
          ''
        ),
        LOCATE(
          '-',
          REPLACE(
            url,
            'http://example.com/component/tags/tag/',
            ''
          )
        ) + 1
      )
    ) as new_url
  FROM test) as new_urls
GROUP BY new_url
HAVING COUNT(*) > 1;
duplicate_ids new_url
1,5,6 http://example.com/tag/thing.html

Query #6 - actually update the table

UPDATE
  test
SET
  url = CONCAT(
    'http://example.com/tag/',
    SUBSTRING(
      REPLACE(
        url,
        'http://example.com/component/tags/tag/',
        ''
      ),
      LOCATE(
        '-',
        REPLACE(
          url,
          'http://example.com/component/tags/tag/',
          ''
        )
      ) + 1
    )
  );

没有要显示的结果.


Query #7 - view the new URLs

SELECT * FROM test;

View on DB Fiddle

Mysql相关问答推荐

MySQL生成的整型计算可以为空吗?

Google Sheet查询以提取数据并用值替换复选框.(差异)

如何在Sequelize中创建限制查询?

使用触发器markdown 10%

多列分组并进行求和

MySQL中的where语句会 destruct 全外连接.

如何在 MySQL Workbench 中设置 DateTime 列的默认值?

如何编写按天数汇总值的sql查询?

如何优化使用多个 LEFT JOIN 和 GROUP BY 子句的慢速 MySQL 查询?

有人可以帮我用 R 编程解决这个问题吗?

如何将结果列中的不同值按其他列sql中的值带入单行

MySQL 8.0.30 正则表达式词匹配特殊字符

Laravel 查询构建器 where() 用于何时产品必须有多个标签(使用 product_tags 数据透视表多对多)

如何显示患者预约中的专业人员姓名?

mysql - 如何加入表中的动态列

MySQL查询根据同一表中其他字段的值更新表中的字段

查询以查找可用时隙

如何使用 phpmyadmin 复制数据库?

将 MySQL 数据库置于版本控制之下?

数据截断:第 1 行的logo列数据太长