我使用以下查询在我的数据库中显示重复的条目(看起来我不小心两次运行该脚本,尽管它可能更多,因为它可能是恶意用户)。 / p>
我使用以下查询,但它实际上并不满足我的要求:
SELECT meta_value, COUNT(meta_value) AS cnt
FROM wp_postmeta
GROUP BY meta_value
HAVING cnt > 1
ORDER BY cnt;
我也希望查询检查重复的条目是否具有相同的post_id
和meta_key
。
所以,例如:
meta_id post_id meta_key meta_value
1 10 size large
2 10 colour blue
3 10 size large
4 11 size large
meta_id
1和3是重复的条目。
我想删除所有这些条目中的所有条目。
有没有办法通过单个查询执行此操作?如果我可以先查看行以确保查询按预期执行,那就太棒了。
提前致谢,
答案 0 :(得分:4)
试试这个 -
DELETE t2
FROM wp_postmeta t1
INNER JOIN wp_postmeta t2
ON t1.post_id = t2.post_id
AND t1.meta_key = t2.meta_key
AND t1.meta_value = t2.meta_value
AND t1.meta_id < t2.meta_id
请注意@ RolandBouman关于您要删除的行的引用的警告。
答案 1 :(得分:2)
“我也希望查询检查重复的条目是否具有相同的post_id和meta_key。”
然后,也可以使用组中的那些。
SELECT meta_value, COUNT(meta_value) AS cnt
FROM wp_postmeta
GROUP BY post_id, meta_key, meta_value
HAVING cnt > 1
ORDER BY cnt;
“我想删除所有这些条目中的所有条目。”
遗憾的是,这在MySQL中并不那么容易。 (见http://dev.mysql.com/doc/refman/5.5/en/delete.html)
有一种称为多表DELETE语法的东西,但是如果你需要加入与要删除的表相同的表,它就没用了。使用子查询也不会飞,因为您无法从与要删除的表相同的表中进行选择。
不幸的是,最简单的方法是根据查询分组创建一个临时表,并使用它来加入:
CREATE TABLE wp_postmeta_delete
AS
SELECT MIN(meta_id) meta_id
, post_id
, meta_key
, meta_value
FROM wp_postmeta
GROUP BY post_id, meta_key, meta_value
HAVING count(*) > 1;
DELETE wp_postmeta.*
FROM wp_postmeta
INNER JOIN wp_postmeta_delete t2
ON wp_postmeta.meta_id != t2.meta_id
AND wp_postmeta.post_id = t2.post_id
AND wp_postmeta.meta_key = t2.meta_key
AND wp_postmeta.meta_value = t2.meta_value;
删除行后,您可以丢弃临时表:
DROP TABLE wp_postmeta_delete;
请注意,在许多情况下,仅删除重复项可能不够好;如果其他表指向重复的行,那么您应该将这些引用迁移到指向您要保留的相应唯一行。
答案 2 :(得分:1)
delete from wp_postmeta
where meta_id in
(select meta_id
from
(select meta_key, meta_value, post_id
from wp_postmeta
group by meta_key, meta_value, post_id
having count(*) > 1) problemGroups
inner join wp_postmeta a
on a.meta_key = problemGroups.meta_key
and a.meta_value = problemGroups.meta_value
and a.post_id = problemGroups.post_id) allIDs
and meta_id not in
(select min(meta_id)
from
(select meta_key, meta_value, post_id
from wp_postmeta
group by meta_key, meta_value, post_id
having count(*) > 1) problemGroups
inner join wp_postmeta a
on a.meta_key = problemGroups.meta_key
and a.meta_value = problemGroups.meta_value
and a.post_id = problemGroups.post_id
group by problemGroups.meta_key, meta_value, port_id) minIDS
答案 3 :(得分:0)
我还没有测试过,但这样的事情应该可行(这假设你的select语句抓住了你想要的东西)
DELETE FROM wp_postmeta
WHERE meta_id IN (
SELECT meta_id
FROM wp_postmeta
GROUP BY meta_value
HAVING COUNT(meta_value) > 1
ORDER BY cnt
);