我将数据从数据库传输到另一个数据库。原始表具有以下结构(其中key contact
是布尔值):
+------------+-----------+-------------+
| contact_id | school_id | key_contact |
+------------+-----------+-------------+
| 1 | 1 | 1 |
| 2 | 2 | 0 |
| 3 | 2 | 1 |
| 4 | 2 | 1 |
| 5 | 3 | 0 |
+------------+-----------+-------------+
我希望将其变为以下形状,其中display_order
是具有school_id
的复合唯一索引:
+------------+-----------+---------------+
| contact_id | school_id | display_order |
+------------+-----------+---------------+
| 1 | 1 | 1 |
| 2 | 2 | 3 |
| 3 | 2 | 1 |
| 4 | 2 | 2 |
| 5 | 3 | 1 |
+------------+-----------+---------------+
逻辑是key_contact = 1
然后display_order
应为1,除非contact_id
具有相同school_id
的{{1}}已经有display_order
且值{ 1,然后它应该插入school_id
唯一的增量可用值。然后我想插入key_contact = 0
分配key_contact
唯一可用的school_id
整数的所有联系人。
我为这两列创建了一个唯一索引:
UNIQUE KEY `contact_school_display_order_school_id_unique` (`display_order`,`school_id`)
我已尝试使用INSERT... ON DUPLICATE KEY UPDATE
,但我真的想要一些东西,在重复键上,将插入值的值递增到school_id
唯一的下一个整数。
任何指针都将非常感激。
答案 0 :(得分:1)
从表格contacts1
迁移到contacts2
insert into contacts2
select
c1.contact_id,
c1.school_id,
count(c2.contact_id) as display_order
from contacts1 c1
join contacts1 c2
on c2.school_id = c1.school_id
and (
c2.key_contact > c1.key_contact
or
c2.key_contact = c1.key_contact and c2.contact_id <= c1.contact_id
)
group by c1.contact_id, c1.school_id
order by c1.contact_id;
<强>解释强>
关键逻辑处于连接条件:
c2.key_contact > c1.key_contact
or
c2.key_contact = c1.key_contact and c2.contact_id <= c1.contact_id
此条件定义c2
的行与给定c1
的行相比,给定学校的联系优先级更高或相等。 (如果contact_id
相同,则优先级相等。)在SELECT
部分中,我们从c1(group by c1.contact_id
)开始计算每个contact_id具有更高或相同优先级的所有行。
c2.key_contact > c1.key_contact
仅在c1.key_contact=0
和c2.key_contact=1
时才有效。因此,此条件中找到的c2
的每一行都具有更高的优先级并将被计算在内。
c2.key_contact = c1.key_contact and c2.contact_id <= c1.contact_id
如果key_contact
相等,那么我们只计算小于或等于contact_id
的行。
这样可以得到与您对表格进行排序相同的结果:
select *
from contacts1 c1
order by c1.school_id, c1.key_contact desc, c1.contact_id
然后枚举每所学校的行。