基于组

时间:2016-12-27 09:19:33

标签: mysql mariadb auto-increment

问题与使用mysql自动增量有关。我想要实现的是根据客户编号增加ID值。所以基本上我将没有任何顺序的数据集插入到表中。每次插入新客户时,我希望id列增加,但当然保留与客户相关的每一行,请参见下表。有没有办法通过sql实现?我尝试了多个主键并且也考虑了分区,但是我自己无法解决这个问题。

test table

3 个答案:

答案 0 :(得分:2)

你可以使用这样的查询:

INSERT INTO autoinc (cid,info,customer)
SELECT
    COALESCE(max(cid),0) +1
    , 'A Customer 1'
    , 12345
FROM autoinc
WHERE customer = 12345;

<强>样品

mysql> SELECT * from autoinc;
Empty set (0,00 sec)

mysql> INSERT INTO autoinc (cid,info,customer)
    -> SELECT
    ->     COALESCE(max(cid),0) +1
    ->     , 'A Customer 1'
    ->     , 12345
    -> FROM autoinc
    -> WHERE customer = 12345;
Query OK, 1 row affected (0,00 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> SELECT * from autoinc;
+----+------+--------------+----------+
| id | cid  | info         | customer |
+----+------+--------------+----------+
|  1 |    1 | A Customer 1 |    12345 |
+----+------+--------------+----------+
1 row in set (0,00 sec)

mysql> INSERT INTO autoinc (cid,info,customer)
    -> SELECT
    ->     COALESCE(max(cid),0) +1
    ->     , 'A Customer 1'
    ->     , 12345
    -> FROM autoinc
    -> WHERE customer = 12345;
Query OK, 1 row affected (0,00 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> SELECT * from autoinc;
+----+------+--------------+----------+
| id | cid  | info         | customer |
+----+------+--------------+----------+
|  1 |    1 | A Customer 1 |    12345 |
|  2 |    2 | A Customer 1 |    12345 |
+----+------+--------------+----------+
2 rows in set (0,00 sec)

mysql> INSERT INTO autoinc (cid,info,customer)
    -> SELECT
    ->     COALESCE(max(cid),0) +1
    ->     , 'B Customer 2'
    ->     , 9876
    -> FROM autoinc
    -> WHERE customer = 9876;
Query OK, 1 row affected (0,00 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> SELECT * from autoinc;
+----+------+--------------+----------+
| id | cid  | info         | customer |
+----+------+--------------+----------+
|  1 |    1 | A Customer 1 |    12345 |
|  2 |    2 | A Customer 1 |    12345 |
|  3 |    1 | B Customer 2 |     9876 |
+----+------+--------------+----------+
3 rows in set (0,00 sec)

mysql> INSERT INTO autoinc (cid,info,customer)
    -> SELECT
    ->     COALESCE(max(cid),0) +1
    ->     , 'A Customer 1'
    ->     , 12345
    -> FROM autoinc
    -> WHERE customer = 12345;
Query OK, 1 row affected (0,00 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> SELECT * from autoinc;
+----+------+--------------+----------+
| id | cid  | info         | customer |
+----+------+--------------+----------+
|  1 |    1 | A Customer 1 |    12345 |
|  2 |    2 | A Customer 1 |    12345 |
|  3 |    1 | B Customer 2 |     9876 |
|  4 |    3 | A Customer 1 |    12345 |
+----+------+--------------+----------+
4 rows in set (0,00 sec)

mysql>

答案 1 :(得分:0)

您可能需要为每位客户提供ID的不同值。实现此目的的最简单方法是使用AUTO_INCREMENT列作为表格的PK

这是一个实现细节,对于连续插入的行,AUTO_INCREMENT列具有连续值。而之前的陈述甚至都不是真的。它只是发生了一些时间,不能保证。如果在回滚的事务中包含INSERT语句,则会跳过该插入生成的值。此外,如果使用INSERT的{​​{1}}语句尝试插入多行但其中一些已经存在于表中,则会跳过为重复键生成的ON DUPLICATE KEYS UPDATE

我想强调的是,尝试使用ID列来获取连续值并且甚至不可能 < / p>

回到你的问题,如果列AUTO_INCREMENT是表的ID且其类型是PK,那么MySQL保证不会有两行具有相同的值INT AUTO_INCREMENT列,这也满足了为ID中具有相同值的所有行ID提供不同值的需要。

答案 2 :(得分:0)

您可以使用存储过程在程序上执行此操作,我不会详细说明(除非请求),因为它不是一个简单的查询(正如您所要求的那样)。

一个hacky解决方案是批量插入新的连接表:

CREATE TABLE auto_inc_customer_id (
   id INT UNSIGNED NOT NULL AUTO_INCREMENT,
   customer_id INT UNSIGNED NOT NULL, -- Could/should add a FK constraint
   PRIMARY KEY (id)
) ENGINE=innodb;

INSERT INTO auto_inc_customer_id SELECT NULL, DISTINCT(Customer) FROM YourExistingTable;

请参阅:http://dev.mysql.com/doc/refman/5.7/en/ansi-diff-select-into-table.html