MySQL auto-increment based on group

倾然丶 夕夏残阳落幕 提交于 2019-12-02 10:09:18

you can use a query like this:

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

sample

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>

What you probably need is to have different values for ID for each customer. The easiest way to achieve this is to use an AUTO_INCREMENT column as PK of your table.

It is an implementation detail that for consecutively inserted rows an AUTO_INCREMENT column has consecutive values. And the previous statement is not even true. It just happens some times, it is not guaranteed. If an INSERT statement is enclosed in a transaction that is rolled back, the value generated by that insert is skipped. Also, if an INSERT statements that use ON DUPLICATE KEYS UPDATE tries to insert many rows but some of them already exist in the table then the IDs generated for the duplicate keys are skipped.

What I want to stress out is that there is no point trying to get consecutive values using an AUTO_INCREMENT column and it is not even possible.

Back to your problem, if the column ID is the PK of the table and its type is INT AUTO_INCREMENT then MySQL guarantees there won't be two rows having the same value in the ID column and this also satisfies your need to have different values for ID for all the rows with the same value in customer.

You could procedurally do this using a stored procedure, which I won't elaborate on (unless requested) as it isn't a simple query (as you're asking for).

A hacky solution would be to bulk insert into a new joining table:

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;

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!