如何删除MySQL中指定SELECT查询结果对应的行?
最佳删除方法推荐
嘿,针对你要删除那类符合ip对应port=445且出现次数恰好为4的记录的需求,我整理了几种靠谱的方法,你可以根据自己使用的数据库类型来选择:
方法一:用CTE(公共表表达式)清晰定位目标记录
CTE的好处是可读性极强,先明确要删除的关联ID,再执行删除,不容易出错:
WITH TargetIPs AS ( -- 先找出符合条件的iper.id(关联trafikk表的外键) SELECT iper.id FROM trafikk INNER JOIN iper ON iper.id = trafikk.FK_ID WHERE trafikk.port = 445 GROUP BY iper.id, iper.IP -- 这里加上iper.id避免分组歧义,兼容严格模式 HAVING COUNT(trafikk.port) = 4 ) -- 删除trafikk中匹配的记录 DELETE FROM trafikk WHERE FK_ID IN (SELECT id FROM TargetIPs) AND port = 445;
方法二:直接用DELETE JOIN(适合MySQL等支持的数据库)
如果你用的是MySQL,这种方式更直接,把查询逻辑和删除合并:
DELETE t FROM trafikk t INNER JOIN ( SELECT iper.id FROM trafikk INNER JOIN iper ON iper.id = trafikk.FK_ID WHERE trafikk.port = 445 GROUP BY iper.id, iper.IP HAVING COUNT(*) = 4 ) AS target ON t.FK_ID = target.id WHERE t.port = 445;
重要前置步骤:先测试再删除!
不管用哪种方法,一定要先测试要删除的记录是否正确,把DELETE改成SELECT *就行:
-- 测试用:查看即将被删除的所有记录 SELECT * FROM trafikk WHERE FK_ID IN ( SELECT iper.id FROM trafikk INNER JOIN iper ON iper.id = trafikk.FK_ID WHERE trafikk.port = 445 GROUP BY iper.id, iper.IP HAVING COUNT(trafikk.port) = 4 ) AND port = 445;
如果你的数据库支持事务(比如MySQL InnoDB、PostgreSQL、SQL Server),建议先开启事务执行删除,确认没问题再提交,万一删错了还能回滚:
BEGIN TRANSACTION; -- 执行你的删除语句 DELETE FROM trafikk WHERE FK_ID IN (SELECT id FROM TargetIPs) AND port = 445; -- 检查删除的行数是否符合预期(MySQL用ROW_COUNT(),其他库可以重新查询计数) SELECT ROW_COUNT(); -- 没问题就提交,有问题就回滚 COMMIT; -- ROLLBACK;
小提示
你原来的SELECT语句里GROUP BY只写了iper.IP,在部分数据库的严格模式下会报错(因为trafikk.port没在分组或聚合里),所以建议分组时加上iper.id和trafikk.port,避免语法问题。
内容的提问来源于stack exchange,提问作者Tore




