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

MySQL-表中的重复行具有由JOIN确定的不同列值,mysql,join,sql-insert,Mysql,Join,Sql Insert,我在编写INSERT语句来复制行时有点困难,但是在另一个表中定义了不同的键值。键可能不一定具有相同的值,因此这就是连接的作用 Roles RoleID Name ------------------------- 3 ROLE_ADMIN 12 ROLE_OPERATOR_ADMIN 13 ROLE_CARD_ADMIN OperatorRoles RoleID OperatorUserID ------------------

我在编写INSERT语句来复制行时有点困难,但是在另一个表中定义了不同的键值。键可能不一定具有相同的值,因此这就是连接的作用

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

OperatorRoles
RoleID     OperatorUserID
-------------------------
3          5
3          7
我需要做的是,为所有OperatorRoles.OperatorUserID用户分配ROLE\u OPERATOR\u ADMIN和ROLE\u CARD\u ADMIN这两个角色,然后删除任何具有ROLE\u ADMIN角色的OperatorRoles.OperatorUserID行,实际上将ROLE\u 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';

这应该很简单,但我不能让它工作。提前谢谢

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

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';

在用@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';

谢谢这并没有产生预期的结果。我可以使用两个单独的查询来确保结果的正确数量。我已修改您的查询以查看每个查询的结果。此查询返回359行,因此我希望插入的任何INSERT都具有相同的计数:SELECT opRoles.*FROM OperatorRoles opRoles JOIN Roles r ON opRoles.RoleID=r.RoleID,其中r.Name='ROLE_ADMIN';空间不足,无法添加上面修改的查询。这里是:将忽略插入OperatorRoles RoleID,OperatorUserID从角色中选择nr.NewRoleId,opRoles.OperatorUserID r.RoleID=r.RoleID交叉连接从角色r中选择RoleID作为NewRoleId,其中r.Name='ROLE_OPERATOR_ADMIN'nr其中r.Name='ROLE_ADMIN';这将生成2435个插入行。这基本上是我回答中的第二个查询。from子句中的表刚刚被重新排列,以将交叉连接放在第一位。