我有以下MySQL表:
CREATE TABLE notification
(`id` int, `person_id` int, `rule_id` int, `account_id` int, `account_display_name` varchar(16))
;
INSERT INTO notification
(`id`, `person_id`, `rule_id`, `account_id`, `account_display_name`)
VALUES
(1, 1, 1, 1, 'Muad''Dib'),
(2, 1, 1, 2, 'Kwisatz Haderach'),
(3, 1, 2, 2, 'Kwisatz Haderach'),
(4, 2, 1, 3, 'Duncan'),
(5, 2, 2, 4, 'Duncan Idaho')
;
CREATE TABLE person
(`id` int, `name` varchar(6), `organization_id` int)
;
INSERT INTO person
(`id`, `name`, `organization_id`)
VALUES
(1, 'paul', 1),
(2, 'duncan', 1),
(3, 'paul', 2),
(4, 'duncan', 2),
(5, 'paul', 3),
(6, 'duncan', 3)
;
CREATE TABLE account
(`id` int, `display_name` varchar(16), `person_id` int)
;
INSERT INTO account
(`id`, `display_name`, `person_id`)
VALUES
(1, 'Muad''Dib', 1),
(2, 'Kwisatz Haderach', 1),
(3, 'Duncan', 2),
(4, 'Duncan Idaho', 2),
(5, 'Muad''Dib', 3),
(6, 'Kwisatz Haderach', 3),
(7, 'Duncan', 4),
(8, 'Duncan Idaho', 4),
(9, 'Muad''Dib', 5),
(10, 'Kwisatz Haderach', 5),
(11, 'Duncan', 6),
(12, 'Duncan Idaho', 6)
;
CREATE TABLE organization
(`id` int, `name` varchar(17))
;
INSERT INTO organization
(`id`, `name`)
VALUES
(1, 'atreides'),
(2, 'atreides_dev'),
(3, 'atreides_research')
;
CREATE TABLE rule
(`id` int, `name` varchar(14))
;
INSERT INTO rule
(`id`, `name`)
VALUES
(1, 'bug'),
(2, 'false_positive')
;
从概念上讲,当发生与notification
相关的事件时,所讨论的系统会生成person
。 notification
是否生成由rule
决定(person
和rule
之间的关系在其他地方定义,但这不在此问题的范围内)。为notification
生成的每个person
都与该account
拥有的person
相关,并且还包含({normalized){ account_display_name
。
请注意,account
也与一个person
正相关。
当前,我在特定organization
中有多个notifications
的一组accounts
(具有相关的persons
)。但是我需要根据导致organization
的{{1}}将这些notifications
移到不同的副本organizations
(带有副本persons
和accounts
)
下面是我尝试执行的迁移类型的示例。
相关表的状态
rule
通知的初始状态
notification
通知的结束状态
person
+----+--------+-----------------+
| id | name | organization_id |
+----+--------+-----------------+
| 1 | paul | 1 |
| 2 | duncan | 1 |
| 3 | paul | 2 |
| 4 | duncan | 2 |
| 5 | paul | 3 |
| 6 | duncan | 3 |
+----+--------+-----------------+
organization
+----+-------------------+
| id | name |
+----+-------------------+
| 1 | atreides |
| 2 | atreides_dev |
| 3 | atreides_research |
+----+-------------------+
account
+----+------------------+-----------+
| id | display_name | person_id |
+----+------------------+-----------+
| 1 | Muad'Dib | 1 |
| 2 | Kwisatz Haderach | 1 |
| 3 | Duncan | 2 |
| 4 | Duncan Idaho | 2 |
| 5 | Muad'Dib | 3 |
| 6 | Kwisatz Haderach | 3 |
| 7 | Duncan | 4 |
| 8 | Duncan Idaho | 4 |
| 9 | Muad'Dib | 5 |
| 10 | Kwisatz Haderach | 5 |
| 11 | Duncan | 6 |
| 12 | Duncan Idaho | 6 |
+----+------------------+-----------+
rule
+----+----------------+
| id | name |
+----+----------------+
| 1 | bug |
| 2 | false_positive |
+----+----------------+
如您所见,+----+-----------+---------+------------+----------------------+
| id | person_id | rule_id | account_id | account_display_name |
+----+-----------+---------+------------+----------------------+
| 1 | 1 | 1 | 1 | Muad'Dib |
| 2 | 1 | 1 | 2 | Kwisatz Haderach |
| 3 | 1 | 2 | 2 | Kwisatz Haderach |
| 4 | 2 | 1 | 3 | Duncan |
| 5 | 2 | 2 | 4 | Duncan Idaho |
+----+-----------+---------+------------+----------------------+
的{{1}}和+----+-----------+---------+------------+----------------------+
| id | person_id | rule_id | account_id | account_display_name |
+----+-----------+---------+------------+----------------------+
| 1 | 3 | 1 | 5 | Muad'Dib |
| 2 | 3 | 1 | 6 | Kwisatz Haderach |
| 3 | 5 | 2 | 10 | Kwisatz Haderach |
| 4 | 4 | 1 | 7 | Duncan |
| 5 | 6 | 2 | 12 | Duncan Idaho |
+----+-----------+---------+------------+----------------------+
已根据person_id
account_id
进行了更新。具体来说:
notifications
notification's
(ID 1)生成的每个rule_id
被移到notification
中相应的bug
和rule
副本中person
(ID 2)。account
atreides_dev
(ID 2)生成的每个organization
被移到notification
中相应的false_positive
和rule
副本中person
(ID 3)。我编写了一个SQL查询,我相信它会基于account
选择正确的atreides_research
和organization
,但是我不确定在其中使用最佳方法UPDATE语句,这样每个notification.person_id
都会正确更新。
这是SELECT:
notification.account_id
请注意,SELECT指定了源notification.rule_id
(ID 1),目的地notification
(ID 2)和select p_replica.id, acc_replica.id as account_id
from (select p.name, person_id, rule_id, account_id, account_display_name from notification n
inner join person p
on n.person_id = p.id
where p.organization_id = 1
and n.rule_id in (1)) as notifications
inner join person p_replica
on p_replica.name = notifications.name
and p_replica.organization_id = 2
inner join account acc_replica
on acc_replica.person_id = p_replica.id
and acc_replica.display_name = notifications.account_display_name;
,其organization
需要迁移。回想一下,这是基于organization
到目标rule
的映射。换句话说,选择所有更新的notifications
将需要根据rule
-> organization
的每个映射执行一次此查询。
执行此迁移的UPDATE查询是什么样的?
这里是一个SQL Fiddle。