MySQL - 表中的重复行,具有由JOIN确定的不同列值

时间:2015-01-21 15:48:56

标签: mysql join sql-insert

我在编写INSERT语句以复制行时遇到一些困难,但在另一个表中定义了不同的KEY值。 KEY可能不一定具有相同的值,因此JOIN进入的位置。

Roles
RoleID     Name
-------------------------
3          ROLE_ADMIN
12         ROLE_OPERATOR_ADMIN
13         ROLE_CARD_ADMIN

OperatorRoles
RoleID     OperatorUserID
-------------------------
3          5
3          7

我需要做的是为所有OperatorRoles.OperatorUserID用户分配ROLE_OPERATOR_ADMIN和ROLE_CARD_ADMIN的角色,然后删除任何具有ROLE_ADMIN角色的OperatorRoles.OperatorUserID行(基本上将ROLE_ADMIN角色分解为两个)。

OperatorRoles
RoleID     OperatorUserID
-------------------------
12         5
12         7
13         5
13         7

这是我到目前为止所提出的,但它试图插入比它应该更多的记录:

INSERT IGNORE INTO OperatorRoles (RoleID, OperatorUserID)
SELECT r.RoleID, opRoles.OperatorUserID
FROM Roles r JOIN OperatorRoles opRoles ON r.RoleID = r.RoleID
WHERE r.Name = 'ROLE_OPERATOR_ADMIN';

这应该很简单,但我无法使其发挥作用。提前谢谢!

2 个答案:

答案 0 :(得分:0)

我认为你基本上想要这样的东西:

INSERT IGNORE INTO OperatorRoles (RoleID, OperatorUserID)
    SELECT nr.NewRoleId, opRoles.OperatorUserID
    FROM Roles r JOIN
         OperatorRoles opRoles
         ON r.RoleID = r.RoleID CROSS JOIN
         (SELECT 12 as NewRoleId UNION ALL SELECT 13) nr
    WHERE r.Name = 'ROLE_ADMIN';

DELETE opRoles
    FROM OperatorRoles opRoles
         ON r.RoleID = r.RoleID
    WHERE r.Name = 'ROLE_ADMIN';

这听起来像是一次性操作,因此第一个查询只使用角色ID,而不是联接回来获取名称。但是,你可以把它写成:

INSERT IGNORE INTO OperatorRoles (RoleID, OperatorUserID)
    SELECT nr.NewRoleId, opRoles.OperatorUserID
    FROM Roles r JOIN
         OperatorRoles opRoles
         ON r.RoleID = r.RoleID CROSS JOIN
         (SELECT RoleId as NewRoleId
          FROM Roles r
          WHERE r.Name IN ('ROLE_OPERATOR_ADMIN', 'ROLE_CARD_ADMIN')
         ) nr
    WHERE r.Name = 'ROLE_ADMIN';

答案 1 :(得分:0)

在用@ Gordon-Linoff发布的内容再次思考之后,我想出了这个并且它做了我想要的事情:

INSERT IGNORE INTO OperatorRoles(RoleID, OperatorUserID)
SELECT nr.newRoleID, opRoles.OperatorUserID
FROM
    (SELECT r1.RoleID AS newRoleID
    FROM Roles r1
    WHERE r1.Name IN ('ROLE_OPERATOR_ADMIN' , 'ROLE_CARD_ADMIN')) nr
CROSS JOIN OperatorRoles oproles
JOIN Roles r2 ON opRoles.RoleID = r2.RoleID
WHERE r2.Name = 'ROLE_ADMIN';