好的,这是(可能)一个非常简单的问题,但我恐怕几乎不知道MySQL,所以请忍受我。我只是试图从一个表中删除不受另一个表中的外键约束的每一行 - 一个特定的表,这里只涉及两个表。 create语句看起来有点像:
CREATE TABLE `testschema`.`job` (
`Job_Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`Comment` varchar(255) DEFAULT NULL,
PRIMARY KEY (`Job_Id`) USING BTREE,
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE `ermieimporttest`.`jobassignment` (
`JobAssignment_Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`JobId` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`JobAssignment_Id`),
KEY `FK_jobassignment_1` (`JobId`),
CONSTRAINT `FK_jobassignment_1` FOREIGN KEY (`JobId`) REFERENCES `job` (`Job_Id`),
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
我的任何SQL语句都是:
DELETE FROM job USING job INNER JOIN jobAssignment WHERE job.Job_Id != jobAssignment.JobId;
我认为这是正确的 - 它应该删除作业表中的每个作业,而该作业表中没有作业作业,因为它是外键。但是,当我尝试执行它时失败并出现以下错误:
无法删除或更新父行: 外键约束失败 (
testdatabase
。jobassignment
, 约束FK_jobassignment_1
FOREIGN KEY(JobId
)参考job
(Job_Id
))
那么我做错了什么傻事?
编辑:像往常一样,我在帖子发布后几秒钟就找到了答案。我使用了(完全不同的)查询:DELETE FROM job WHERE Job_Id NOT IN (SELECT JobId FROM jobassignment)
出于好奇,这是更好的方法吗?我最初的想法是否可行?如果是这样,它有什么问题?
答案 0 :(得分:7)
DELETE FROM job USING job
LEFT JOIN jobAssignment ON(job.Job_Id = jobAssignment.JobId)
WHERE jobAssignment.JobId IS NULL;
答案 1 :(得分:5)
您可能需要一个子查询,不确定这是否适用于mySQL,但至少类似于:
DELETE FROM job
WHERE job.Job_Id NOT IN (
SELECT JobId FROM jobAssignment
)
答案 2 :(得分:1)
Naktibalda认为子查询可能效率低下;如果是这样你可以尝试
DELETE FROM job
WHERE NOT EXISTS (SELECT *
FROM jobassignment
WHERE job.Job_Id = jobassignment.Job_Id);
我过去曾经有过IN和NOT IN的糟糕经历;使用NOT EXISTS减少麻烦。