MySQL - table 中的重复行具有由 JOIN 确定的不同列值
MySQL - Duplicate rows in a table with different column value determined by JOIN
我在编写 INSERT 语句来复制行时遇到了一些困难,但在另一个 table 中定义了不同的 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 的角色,然后删除角色为 [的所有 OperatorRoles.OperatorUserID 行=27=](本质上是将 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';
这应该很简单,但我做不到。提前致谢!
我想你基本上想要这样的东西:
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';
我在编写 INSERT 语句来复制行时遇到了一些困难,但在另一个 table 中定义了不同的 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 的角色,然后删除角色为 [的所有 OperatorRoles.OperatorUserID 行=27=](本质上是将 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';
这应该很简单,但我做不到。提前致谢!
我想你基本上想要这样的东西:
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';