如何删除数据库中重复的 Wordpress 帖子

How delete duplicate Wordpress posts in DB

当我 运行 我的 wp_posts table 上的这段代码(使用 phpmyadmin)时,它 returns 一个重复的 post.

SELECT a.ID, a.post_title, a.post_type, a.post_status
FROM wp_posts AS a
 INNER JOIN (
   SELECT post_title, MIN( id ) AS min_id
   FROM wp_posts
   WHERE post_type = 'post'
   AND post_status = 'publish'
   GROUP BY post_title
   HAVING COUNT( * ) > 1
 ) AS b ON b.post_title = a.post_title
AND b.min_id <> a.id
AND a.post_type = 'post'
AND a.post_status = 'publish'

请注意,给定的 post 实际上不是重复的,它只是与另一个具有相同的标题(给定上面的代码查找重复标题的正常行为)。但是,问题是数据库里其实有几百个重复的post(我手动看就能看到),为什么我用上面的代码找不到呢?

编辑:如果我随机查看两个副本,其中一个具有:

ID 9462
post date 2017-03-07 13:06:31
post content "foo"
post title "Les pendules à l'heure"
post status "publish"
post type "post"
guid "http://www.exemple.com/?p=9462"

对方有:

ID 11409
post date 2017-03-07 13:06:31
post content "foo"
post title "Les pendules à l&#039;heure"
post status "publish"
post type "post"
guid "http://www.exemple.com/?p=9462"

谢谢

Try this

DELETE a.*
FROM wp_posts AS a
   INNER JOIN (
      SELECT post_title, MIN( id ) AS min_id
      FROM wp_posts
      WHERE post_type = 'post'
      AND post_status = 'publish'
      GROUP BY post_title
      HAVING COUNT( * ) > 1
   ) AS b ON b.post_title = a.post_title
AND b.min_id <> a.id
AND a.post_type = 'post'
AND a.post_status = 'publish'

这是我设法解决问题的方法...

我注意到尽管重复的 post 之间的标题看起来相同,但其中一个有 apostrophe 而另一个有 ' ;

所以首先我 运行 这个查询是为了查看有多少 post 标题有 postrophes:

SELECT post_title FROM wp_posts WHERE post_title LIKE "%'%",

返回了1825个结果。然后我 运行 以下命令查看有多少 post 标题有 ' ;

SELECT post_title FROM wp_posts WHERE post_title LIKE "%&#039;%"

返回了720个结果。所以我想我会替换所有的 ' ;通过 apostrophes,使用以下查询:

UPDATE wp_posts SET post_title = REPLACE (post_title, '&#039;', '\'');

然后,我可以使用:

SELECT a.ID, a.post_title, a.post_type, a.post_status
FROM wp_posts AS a
 INNER JOIN (
   SELECT post_title, MIN( id ) AS min_id
   FROM wp_posts
   WHERE post_type = 'post'
   AND post_status = 'publish'
   GROUP BY post_title
   HAVING COUNT( * ) > 1
 ) AS b ON b.post_title = a.post_title
AND b.min_id <> a.id
AND a.post_type = 'post'
AND a.post_status = 'publish'

返回了 572 posts,我只是使用以下命令将其删除:

DELETE a.*
FROM wp_posts AS a
   INNER JOIN (
      SELECT post_title, MIN( id ) AS min_id
      FROM wp_posts
      WHERE post_type = 'post'
      AND post_status = 'publish'
      GROUP BY post_title
      HAVING COUNT( * ) > 1
   ) AS b ON b.post_title = a.post_title
AND b.min_id <> a.id
AND a.post_type = 'post'
AND a.post_status = 'publish'

以上方式可能比较慢。你可以用 BIG BOY 的方式来做...

-- 创建临时 table CREATE TABLE posts_temp_table LIKE wp_posts;

-- 添加约束 ALTER TABLE posts_temp_table ADD UNIQUE(YOUR_UNIQUE_FIELD, id);

-- 复制数据 INSERT IGNORE INTO posts_temp_table SELECT * FROM wp_posts;

-- 重命名并删除 RENAME TABLE wp_posts TO old_wp_posts, posts_temp_table TO wp_posts;删除 TABLE old_wp_posts;