问题
The problem is related to autoincrement with mysql. What I'm trying to achieve is to increment an ID value based on the customer number. So basically i insert data sets without any order into a table. Each time a new customer is inserted, i would like the id column to be incremented, but of course kept for every row related to the customer, see the table below. Is there any way to achieve that via sql? I tried my luck with multiple primary keys and also looked into partioning, but was not able to figure it out by myself.
回答1:
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>
回答2:
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 ID
s 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
.
回答3:
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
来源:https://stackoverflow.com/questions/41342306/mysql-auto-increment-based-on-group