【问题标题】:MySQL Copy Records in Many to Many JoinMySQL 在多对多连接中复制记录
【发布时间】:2016-11-01 06:45:21
【问题描述】:

我在 MySQL 中有一个多对多连接,将角色链接到任务(三个表:角色、任务和角色任务)。每个角色和任务都属于一个项目。

Roles Table
id | project_id | role
---|------------|-------------
1  | 1          | Supervisor
2  | 1          | Manager

Tasks Table
id | project_id | task
---|------------|-------------
1  | 1          | Do this
2  | 1          | Do that

role_task Table
role_id | task_id
-----------------
1       | 1
1       | 2
2       | 1

我正在寻找一种纯 SQL 方法来将角色、任务及其关联的多对多连接从一个项目复制到另一个项目。我想完成的是:

Roles Table
id | project_id | role
---|------------|-------------
1  | 1          | Supervisor
2  | 1          | Manager
3  | 2          | Supervisor
4  | 2          | Manager

Tasks Table
id | project_id | task
---|------------|-------------
1  | 1          | Do this
2  | 1          | Do that
3  | 2          | Do this
4  | 2          | Do that

role_task Table
role_id | task_id
--------|--------
1       | 1
1       | 2
2       | 1
3       | 3
3       | 4
4       | 3

我可以毫无问题地复制/复制角色表和任务表中的数据。但是,如何使用新的角色 ID 和任务 ID 复制 role_task 表?我可以在 PHP 中使用循环并获取插入的 id,但更喜欢纯 SQL 解决方案。谢谢

【问题讨论】:

  • 你有 3 个表,即 Roles、Tasks 和 role_task?
  • 我不明白您期望从数据库中得到的确切结果是什么。

标签: php mysql sql stored-procedures many-to-many


【解决方案1】:

我能够做到这一点的唯一明智方法是向保存原始记录 ID 的角色和任务表添加一个字段。 role_task 表保持不变,但我的其他两个表现在如下所示:

roles table
id | project_id | original_id | role
---|------------|-------------|-----
1  | 1          | 0           | Supervisor
2  | 1          | 0           | Manager

tasks table
id | project_id | original_id | task
---|------------|-------------|-----
1  | 1          | 0           | Do this
2  | 1          | 0           | Do that

因此,将角色和任务复制到 project_id 为 3 的 SQL 是:

INSERT roles
SELECT NULL, 3, id, role FROM Roles WHERE project_id = 1

INSERT tasks
SELECT NULL, 3, id, task FROM Tasks WHERE project_id = 1

然后,复制多对多表:

INSERT role_task
SELECT r.id, t.id
FROM role_task AS rt
LEFT JOIN roles AS r ON rt.role_id = r.original_id
LEFT JOIN tasks AS t ON rt.task_id = t.original_id
WHERE  r.project_id = 3
AND    t.project_id = 3

【讨论】:

    【解决方案2】:

    如果任务和角色表是自动递增的,您可以执行以下操作……

    请注意,我使用 3 作为 project_id,但这可以是从数据库中的另一个表中查找..

    INSERT INTO tasks (project_id, task) SELECT DISTINCT 3 ,`task` FROM `tasks`;
    
    INSERT INTO roles (project_id, role) SELECT DISTINCT 3,`role` FROM `roles`;
    
    INSERT INTO role_tasks (task_id, role_id) SELECT tasks.id AS task_id, roles.id AS role_id FROM `tasks` CROSS JOIN `roles`  WHERE tasks.project_id=3 AND roles.project_id=3
    

    【讨论】:

    • role_task 表中的数据不能通过交叉连接来构造——它不是一个一切都对一切的关系。在我的示例中,“经理”(id=2) 仅分配了“执行此操作”(id=1) 任务,而不是“执行该操作”(id=2) 任务。
    猜你喜欢
    • 1970-01-01
    • 2013-02-12
    • 1970-01-01
    • 2023-03-09
    • 2019-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多