如果重复,则插入一列唯一复合键的插入增量值

时间:2016-03-09 11:59:10

标签: mysql

我将数据从数据库传输到另一个数据库。原始表具有以下结构(其中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唯一的下一个整数。

任何指针都将非常感激。

1 个答案:

答案 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;

sqlfiddle demo

<强>解释

关键逻辑处于连接条件:

            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=0c2.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

然后枚举每所学校的行。