开发者

Using SQL to perform unique delete

I have a few tables in MySQL like so:

A ---- A_has_B ---- B
    (many to many)  |
                    |
C ---- C_has_B-------
    (many to many)

I need to delete rows from B given that:

  • The row t开发者_如何学运维o be deleted are referenced in C_has_B by C.C_ID
    • The row to be deleted are not referenced by other C.C_IDs in C_has_B
    • The row to be delete is also not referenced in A_has_B

I am able to get all the rows to be deleted referenced by C.ID using:

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;

I am not too sure how I can implement the last 2 conditions. Is it even possible to do this with just 1 query?


You want to delete rows from B that are referenced only once in C_has_B and not referenced by A_has_B.

With subqueries:

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
    )

Without subqueries:

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)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜