MySQL试图删除所有不受外键约束的行

时间:2010-07-02 10:18:34

标签: mysql foreign-keys sql-delete

好的,这是(可能)一个非常简单的问题,但我恐怕几乎不知道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;

我认为这是正确的 - 它应该删除作业表中的每个作业,而该作业表中没有作业作业,因为它是外键。但是,当我尝试执行它时失败并出现以下错误:

  

无法删除或更新父行:   外键约束失败   (testdatabasejobassignment,   约束FK_jobassignment_1   FOREIGN KEY(JobId)参考job   (Job_Id))

那么我做错了什么傻事?

编辑:像往常一样,我在帖子发布后几秒钟就找到了答案。我使用了(完全不同的)查询:

DELETE FROM job WHERE Job_Id NOT IN (SELECT JobId FROM jobassignment) 

出于好奇,这是更好的方法吗?我最初的想法是否可行?如果是这样,它有什么问题?

3 个答案:

答案 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减少麻烦。