简体   繁体   中英

In MySQL, how can I do a DELETE based on the result from a table where I did an INNER JOIN with the same table?

OK, so I do suck at MySQL, but here is basically what I want to do:

delete from course_plan_relationships
where course_plan_relationships.id not in ( 
    select course_plan_relationships.id
    from daily_plans inner join 
    course_plan_relationships on daily_plans.id=course_plan_relationships.daily_plan_id
);

To give you an idea of what's happening, I'll show you the subquery and its result:

mysql> select course_plan_relationships.id from daily_plans inner join 
course_plan_relationships on daily_plans.id=course_plan_relationships.daily_plan_id;
+----+
| id |
+----+
|  1 |
| 13 |
+----+

So basically, I want to delete all items in course_plan_relationships, where its id field is not in that table I generated there in the subquery.

The error I get is:

ERROR 1093 (HY000): You can't specify target table 'course_plan_relationships' for update in FROM clause

What I've basically gotten is that for some reason MySQL won't let you DELETE or UPDATE based on a sub-query involving the same table.

That's fine, and here's a supposed workaround: http://www.xaprb.com/blog/2006/06/23/how-to-select-from-an-update-target-in-mysql/

But its for UPDATE and doesn't use the "in" syntax.

I'm really new to this stuff so any help would be super appreciated. I haven't had any luck using the "AS blahothertablename" kind of syntax (keep getting syntax errors), and I also can't figure out how to store the initial subquery as a temporary result (again, syntax errors).

Using multi-table syntax in the delete, you don't need the sub-query:

DELETE course_plan_relationships
FROM course_plan_relationships LEFT JOIN
daily_plans ON course_plan_relationships.daily_plan_id = daily_plans.id
WHERE daily_plans.id IS NULL;

http://dev.mysql.com/doc/refman/5.0/en/delete.html

According to your workaround, something like this should work:

delete from course_plan_relationships where course_plan_relationships.id not in 
(
  select x.id from 
   (
     select course_plan_relationships.id from daily_plans 
     inner join course_plan_relationships
     on daily_plans.id=course_plan_relationships.daily_plan_id
   ) AS x
) 

I think this is equivalent to what you want (assuming that course_plan_relationships.id is the primary key of the table):

DELETE FROM course_plan_relationships AS cpr
WHERE NOT EXISTS
    ( SELECT *
      FROM daily_plans AS dp 
      WHERE dp.id = cpr.daily_plan_id
    ) ;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM