我在 MySQL 中有几个这样的表:
A ---- A_has_B ---- B
(many to many) |
|
C ---- C_has_B-------
(many to many)
鉴于以下情况,我需要从 B 中删除行:
- 要删除的行在 C_has_B 中由 C.C_ID 引用
- 要删除的行未被 C_has_B 中的其他 C.C_ID 引用
- 要删除的行在A_has_B中也没有被引用
我能够使用以下方法获取 C.ID 引用的所有要删除的行:
DELETE * FROM C
JOIN C_has_B
ON(C.C_ID = C_has_B.C_ID)
JOIN B
on(C_has_B.B_ID = B.B_ID)
where C.C_ID = 1;
我不太确定如何实现最后两个条件。甚至可以只用 1 个查询来做到这一点吗?
最佳答案
您想从 B 中删除仅在 C_has_B 中引用一次且未被 A_has_B 引用的行。
使用子查询:
DELETE B
FROM
B
JOIN
(
-- get rows from C_has_B that reference B_ID only once
SELECT B_ID, Count(*)
FROM C_has_B
GROUP BY B_ID
HAVING Count(*) = 1
)
as C_has_B_once
on (B.B_ID = C_has_B_once.B_ID)
WHERE
-- filter to rows not referenced by A_has_B
B.B_ID not in (
SELECT B_ID
FROM A_has_B
)
没有子查询:
DELETE B
FROM
B
-- get rows from C_has_B that reference B_ID only once
-- (find 1 match via C_has_B1 and make sure there are no other C_IDs referencing the same B_ID via C_has_B2)
JOIN
C_has_B as C_has_B1
on (B.B_ID = C_has_B1.B_ID) and (A_has_B.B_ID = NULL)
LEFT JOIN
C_has_B as C_has_B2
on (C_has_B1.B_ID = C_has_B2.B_ID) and (C_has_B1.C_ID <> C_has_B2.C_ID)
-- filter to rows not referenced by A_has_B
LEFT JOIN
A_has_B
on (B.B_ID = A_has_B.B_ID) and (A_has_B.B_ID = NULL)
WHERE
-- exclude rows that join to C_has_B2
(C_has_B2.C_ID is NULL)
关于mysql - 使用SQL执行唯一删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6868483/