Mysql 如何删除具有唯一值的行?
我想删除表中在Mysql 如何删除具有唯一值的行?,mysql,sql,Mysql,Sql,我想删除表中在setid列中具有唯一值的所有行。我可以这样选择它们: select * from imagesets as a where (select count(*) from imagesets as b where a.setid = b.setid) = 1 删除它们的最佳方式是什么?有更好的方法选择它们吗?我认为以下方法在MySQL中适用: delete i from imagesets i join (select setid, count(*) as
setid
列中具有唯一值的所有行。我可以这样选择它们:
select * from imagesets as a
where (select count(*) from imagesets as b where a.setid = b.setid) = 1
删除它们的最佳方式是什么?有更好的方法选择它们吗?我认为以下方法在MySQL中适用:
delete i from imagesets i join
(select setid, count(*) as cnt
from imagesets
group by setid
having count(*) = 1
) set1
on i.setid = set1.setid;
我认为以下内容将在MySQL中起作用:
delete i from imagesets i join
(select setid, count(*) as cnt
from imagesets
group by setid
having count(*) = 1
) set1
on i.setid = set1.setid;
可以这样做
CREATE TEMPORARY TABLE temp.deletesetids AS
select setid from imagesets as a
where (select count(*) from imagesets as b where a.setid = b.setid) = 1;
DELETE t1 FROM imagesets t1 JOIN temp.deletesetids t2
WHERE t1.SEtId=t2.SEtId;
DROP TABLE temp.deletesetids;
这确实需要您有一个临时
模式
。否则,只需使用当前会话选择即可
CREATE TEMPORARY TABLE temp.deletesetids AS
select setid from imagesets as a
where (select count(*) from imagesets as b where a.setid = b.setid) = 1;
DELETE t1 FROM imagesets t1 JOIN temp.deletesetids t2
WHERE t1.SEtId=t2.SEtId;
DROP TABLE temp.deletesetids;
CREATE TEMPORARY TABLE to_delete AS
SELECT setid FROM imagesets GROUP BY setid HAVING COUNT(*) = 1;
DELETE imagesets FROM imagesets NATURAL JOIN to_delete;
DROP TABLE to_delete;
这确实需要您有一个临时模式
。否则,只需使用当前会话选择
CREATE TEMPORARY TABLE to_delete AS
SELECT setid FROM imagesets GROUP BY setid HAVING COUNT(*) = 1;
DELETE imagesets FROM imagesets NATURAL JOIN to_delete;
DROP TABLE to_delete;
最后一行是可选的。临时表将在会话结束时自动删除
这也同样适用:
DELETE imagesets FROM imagesets NATURAL JOIN (SELECT setid FROM imagesets GROUP BY setid HAVING COUNT(*) = 1) singles;
尽管在DELETE
语句中使用了SELECT
,但MySQL处理此查询的方式似乎不会与表锁定产生冲突。根据进程列表,MySQL在执行此操作时会自动生成一个临时表。我不知道它是否适用于MySQL的每个版本
最后一行是可选的。临时表将在会话结束时自动删除
这也同样适用:
DELETE imagesets FROM imagesets NATURAL JOIN (SELECT setid FROM imagesets GROUP BY setid HAVING COUNT(*) = 1) singles;
尽管在
DELETE
语句中使用了SELECT
,但MySQL处理此查询的方式似乎不会与表锁定产生冲突。根据进程列表,MySQL在执行此操作时会自动生成一个临时表。我不能告诉howover,它适用于MySQL的每个版本。在这种情况下,您很可能需要明确说明要从哪个表中删除:从ImageSet中删除ImageSet…
(-1不是我的)@zerkms。是的,delete语句中缺少了这一点。我不太确定这一疏忽是否值得投反对票。你可以在这里看到它是有效的()。我相信它是有效的,+1可以恢复平衡:-)我更喜欢不创建临时表的方法。我加入并选择了id(唯一键),而不是setid,我忽略了它的存在。在这种情况下,您很可能需要明确说明要从哪个表中删除:从ImageSet中删除ImageSet…
(-1不是我的)@zerkms。是的,delete语句中缺少了这一点。我不太确定这一疏忽是否值得投反对票。你可以在这里看到它是有效的()。我相信它是有效的,+1可以恢复平衡:-)我更喜欢不创建临时表的方法。我加入并选择了id(唯一键),而不是setid,我忽略了它的存在。您可以通过添加限制2
来优化子查询,因为您对任何其他结果都不感兴趣。删除操作如下所述。您可以通过添加限制2
来优化子查询,因为您对任何其他结果都不感兴趣。删除操作如下所述。如果您使用临时表-您不必手动删除它(并且不需要temp
数据库)zerkms,即使它是临时表,您仍然必须删除它。它是临时的,直到您删除它或会话按照我刚才读到的那样进行。尝试创建临时表测试,选择1,2;两次。它给了我一个错误表allready exists。如果您使用临时表-您不必手动删除它(并且不需要temp
数据库)zerkms,您仍然必须删除该表,即使它是一个临时表。它是临时的,直到您删除它或会话按照我刚才读到的那样进行。尝试创建临时表测试,选择1,2;两次。它给了我一个错误表allready exists。DROP table
在这种情况下可能是多余的,不是吗?这需要一些时间。因此,如果您明确地这样做,您的程序必须等待DROP
成功。PS:这就是为什么我说“可能”-如果不是必需的话-我想不出一个好的理由这么做。例如,他可能正在使用PDO和持久连接。它不会在会话之间删除临时表,因为在会话之间不会有“临时表”。此外,如果他不删除表,他将只能在每个会话中运行此脚本一次。是的,这就是“可能”一词的意思:-)删除表在这种情况下可能是多余的,不是吗?这需要一些时间。因此,如果您明确地这样做,您的程序必须等待DROP
成功。PS:这就是为什么我说“可能”-如果不是必需的话-我想不出一个好的理由这么做。例如,他可能正在使用PDO和持久连接。它不会在会话之间删除临时表,因为在会话之间不会有“临时表”。此外,如果他不删除表,他将只能在每个会话中运行此脚本一次。是的,这就是“可能”一词的意思:-)