Вы не удаляете из двух таблиц одновременно.Если таблицы связаны, вы удаляете из дочернего, то из родительского.Если они не связаны, удаление может произойти в любом порядке.Если они не связаны, но имеют другие таблицы в зависимости от них (т.е. они сами являются родителями и имеют детей), то сначала необходимо удалить данные из этих других таблиц.Если реляционные ограничения установлены в режим CASCADE DELETE, то данные дочерней таблицы будут автоматически удаляться при удалении данных родительской таблицы.Если удаление должно происходить как действие «все или ничего» (т. Е. Если второе удаление завершается неудачно после успешного первого удаления, вы не хотите, чтобы первое удаление было успешным), это следует делать в транзакции.
Таким образом:
DELETE FROM wp_postmeta WHERE post_id NOT IN (
SELECT Min(f.post_id)
FROM (SELECT wp_posts.post_title,
Min(wp_postmeta.meta_value) AS minprice
FROM wp_postmeta
JOIN wp_posts
ON wp_postmeta.post_id = wp_posts.id
WHERE wp_posts.post_type = 'Product'
AND wp_postmeta.meta_key = '_regular_price'
GROUP BY wp_posts.post_title) AS x
INNER JOIN (SELECT wp_postmeta.post_id,
wp_posts.post_title,
wp_postmeta.meta_value
FROM wp_postmeta
JOIN wp_posts
ON wp_postmeta.post_id = wp_posts.id
WHERE wp_posts.post_type = 'Product'
AND wp_postmeta.meta_key = '_regular_price'
ORDER BY wp_posts.post_title,
wp_postmeta.meta_value) AS f
ON x.post_title = f.post_title
AND f.meta_value = x.minprice
GROUP BY f.post_title
)
DELETE FROM wp_posts WHERE ID NOT IN (
SELECT Min(f.post_id)
FROM (SELECT wp_posts.post_title,
Min(wp_postmeta.meta_value) AS minprice
FROM wp_postmeta
JOIN wp_posts
ON wp_postmeta.post_id = wp_posts.id
WHERE wp_posts.post_type = 'Product'
AND wp_postmeta.meta_key = '_regular_price'
GROUP BY wp_posts.post_title) AS x
INNER JOIN (SELECT wp_postmeta.post_id,
wp_posts.post_title,
wp_postmeta.meta_value
FROM wp_postmeta
JOIN wp_posts
ON wp_postmeta.post_id = wp_posts.id
WHERE wp_posts.post_type = 'Product'
AND wp_postmeta.meta_key = '_regular_price'
ORDER BY wp_posts.post_title,
wp_postmeta.meta_value) AS f
ON x.post_title = f.post_title
AND f.meta_value = x.minprice
GROUP BY f.post_title
)
Предупреждение
Не запускайте запрос на удаление, данный вам кем-то в Интернете, без предварительного резервного копирования ваших данных.По крайней мере, запустите транзакцию, запустите удаление, выберите результаты и посмотрите на них, чтобы убедиться, что они правильные, используя следующий код:
START TRANSACTION;
DELETE FROM ...
DELETE FROM ...
SELECT * FROM ... -/*to check the deletes worked and didn't remove too much*/
ROLLBACK;
Измените ROLLBACK на COMMIT, когда вы 're happy
Редактировать:
Вариант 1
Заставить метаданные постов зависеть от постов (это может уже иметь место, убедитесь, что удаления каскадируются):
ALTER TABLE posts_meta
ADD CONSTRAINT fk_pm FOREIGN KEY (posts_id) REFERENCES posts(id) ON DELETE CASCADE
Теперь запустите удаление в таблице сообщений, записи posts_meta также исчезнут
Option2
Запустите удаление в таблице сообщений, как указано выше
Используйте следующий запрос дляудалить любую запись из posts_meta, у которой нет соответствующей записи в сообщениях:
DELETE FROM posts_meta WHERE post_id IN (select post_id from(
SELECT pm.post_id
FROM
posts_meta pm
LEFT JOIN
posts p
ON p.id = pm.post_id
WHERE
p.id IS NULL
) i )
Внутренний подзапрос, который находит список идентификаторов, по какой-то причине обернут внутри другого подзапроса;Есть ситуации, когда MySQL откажется от удаления, если шаблон DELETE FROM x WHERE y IN (SELECT x FROM y)
, потому что вы не можете изменить таблицу, из которой выбираете.Заключение в другой выбор - это хак, который заставляет MySQL не рассматривать его как удаление из той же таблицы, которую вы выбираете из