下面不一定使用正确的语法,而是意在表达我的意图:
DELETE FROM wp_posts, wp_postmeta
WHERE wp_posts.ID <> min(f.post_ID), wp_postmeta.post_id <> min(f.post_ID)
(这分别是真正2只删除组合在一个,与用于在第一和第二表WHERE条件。)
其中min(f.post_ID)
来自下方的虚拟表:
SELECT Min(f.post_id),
f.post_title,
f.meta_value
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将受影响的首先删除,因为从子查询表中的项目先删除被删除。)
你不从两个表在同一时间删除。如果表是相关的,你这个孩子,然后父删除。如果他们不相关的删除可以按任何顺序发生。如果他们无关,但有依赖于它们的其他表(即他们是父母自己生孩子),那么数据必须从这些其它表的第一被清零。如果关系限制设置为级联删除模式,则子表中的数据时,将自动父表中的数据被删除删除。如果删除必须发生,因为一个全有或全无(即如果先删除成功后的第二删除失败,你不想先删除成功),应在交易完成。
从而:
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承诺,当你快乐
编辑:
让元取决于职位的职位(它可能已经做的,保证了级联删除):
ALTER TABLE posts_meta
ADD CONSTRAINT fk_pm FOREIGN KEY (posts_id) REFERENCES posts(id) ON DELETE CASCADE
现在我们对posts表的删除,posts_meta条目也将消失
运行您删除的帖子表如上文所建议
使用以下查询删除从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 )
该发现ID列表最里面的子查询包裹的另一个子查询是有原因的内部;有些情况下,MySQL将拒绝删除,如果该模式是DELETE FROM x WHERE y IN (SELECT x FROM y)
因为你不能修改你从选择表的情况。结束工作的另一个选择是导致MySQL不要把它从你从选择相同的表中删除一个黑客
我们的想法是,选择的ID从表wp_posts
和wp_postmeta
到临时表posts
和postmeta
删除。即使你从任何表中删除数据这将保留ID的列表。然后,从表wp_posts
删除数据和wp_postmeta
一个又一个基于ID的在临时表就行了。最后一步是清除临时表(从他们删除数据)。
本次交易以这种方式使用,以允许运行在phpMyAdmin此代码。
代码的优化版本:
BEGIN;
CREATE TEMPORARY TABLE IF NOT EXISTS minPostIds AS
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') 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 wp_posts.ID IN (SELECT ID FROM minPostIds);
DELETE FROM wp_postmeta WHERE wp_postmeta.post_id IN (SELECT ID FROM minPostIds);
DELETE FROM minPostIds;
COMMIT;
这个版本的作品:
BEGIN;
CREATE TEMPORARY TABLE IF NOT EXISTS posts AS
SELECT ID
FROM wp_posts
WHERE wp_posts.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
);
CREATE TEMPORARY TABLE IF NOT EXISTS postmeta AS
SELECT post_id
FROM wp_postmeta
WHERE wp_postmeta.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 wp_posts.ID IN (SELECT ID FROM posts);
DELETE FROM wp_postmeta WHERE wp_postmeta.post_id IN (SELECT post_id FROM postmeta);
DELETE FROM posts;
DELETE FROM postmeta;
COMMIT;
您还可以创建一个存储过程:
CREATE PROCEDURE DeleteFromTables()
BEGIN
CREATE TEMPORARY TABLE IF NOT EXISTS posts
ENGINE=MyISAM
AS (
SELECT ID
FROM wp_posts
WHERE wp_posts.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
)
);
CREATE TEMPORARY TABLE IF NOT EXISTS postmeta
ENGINE=MyISAM
AS (
SELECT post_id
FROM wp_postmeta
WHERE wp_postmeta.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
)
);
START TRANSACTION;
DELETE FROM wp_posts
WHERE wp_posts.ID IN (SELECT ID FROM posts);
DELETE FROM wp_postmeta
WHERE wp_postmeta.post_id IN (SELECT post_id FROM postmeta);
COMMIT;
DELETE FROM posts;
DELETE FROM postmeta;
END;