就问题而言,您要story_category
删除category
.
这是您用于识别要删除的行的原始查询:
SELECT *
FROM story_category
WHERE category_id NOT IN (
SELECT DISTINCT category.id
FROM category INNER JOIN
story_category ON category_id=category.id
);
结合作为原始表NOT IN
的子查询似乎不必要地令人费解。JOIN
这可以使用not exists
相关子查询以更直接的方式表示:
select sc.*
from story_category sc
where not exists (select 1 from category c where c.id = sc.category_id);
现在很容易把它变成一个delete
语句:
delete from story_category
where not exists (select 1 from category c where c.id = story_category.category_id);
这个查询可以在任何 MySQL 版本上运行,也可以在我知道的大多数其他数据库上运行。
DB Fiddle 上的演示:
-- set-up
create table story_category(category_id int);
create table category (id int);
insert into story_category values (1), (2), (3), (4), (5);
insert into category values (4), (5), (6), (7);
-- your original query to identify offending rows
SELECT *
FROM story_category
WHERE category_id NOT IN (
SELECT DISTINCT category.id
FROM category INNER JOIN
story_category ON category_id=category.id);
| 类别 ID |
| ----------: |
| 1 |
| 2 |
| 3 |
-- a functionally-equivalent, simpler query for this
select sc.*
from story_category sc
where not exists (select 1 from category c where c.id = sc.category_id)
| 类别 ID |
| ----------: |
| 1 |
| 2 |
| 3 |
-- the delete query
delete from story_category
where not exists (select 1 from category c where c.id = story_category.category_id);
-- outcome
select * from story_category;
| 类别 ID |
| ----------: |
| 4 |
| 5 |