186

I am trying to alter a table which has no primary key nor auto_increment column. I know how to add an primary key column but I was wondering if it's possible to insert data into the primary key column automatically (I already have 500 rows in DB and want to give them id but I don't want to do it manually). Any thoughts? Thanks a lot.

Carrie Kendall
  • 11,124
  • 5
  • 61
  • 81
FlyingCat
  • 14,036
  • 36
  • 119
  • 198
  • 2
    You can easily do the `alter table` to add the key, but MySQL won't generate IDs for fields which don't already have them. You'll have to manually update the existing fields and then make sure your new auto_increment starts at the right offset - it defaults to '1' and you'd just end up with duplicate key errors anyways. – Marc B Jan 30 '12 at 21:07
  • 4
    @MarcB I just tested, and it did in fact insert the ids for existing rows starting at 1 – Michael Berkowski Jan 30 '12 at 21:09

14 Answers14

322

An ALTER TABLE statement adding the PRIMARY KEY column works correctly in my testing:

ALTER TABLE tbl ADD id INT PRIMARY KEY AUTO_INCREMENT;

On a temporary table created for testing purposes, the above statement created the AUTO_INCREMENT id column and inserted auto-increment values for each existing row in the table, starting with 1.

Michael Berkowski
  • 267,341
  • 46
  • 444
  • 390
  • 2
    Yep, this has been my experience. Never remember having to run a separate script to populate auto_increment ids... – Mike Purcell Jan 30 '12 at 21:11
  • 2
    lol..Thanks. my bad. The green mark is for you since yours is easier to implement then. :D – FlyingCat Jan 30 '12 at 21:24
  • +1, works in 5.1.51-ndb-7.1.9a-log, on table with engine MyISAM – Radu Maris Aug 28 '12 at 13:16
  • 74
    To make it the first column, use `FIRST` e.g `ALTER TABLE tbl1 ADD id INT PRIMARY KEY AUTO_INCREMENT FIRST;` – David Thomas Apr 03 '14 at 07:58
  • Can you please provide query to add primary key in sqlite – Nikkie Sep 03 '15 at 13:06
  • 2
    @Nikkie SQLite's mechanics are quite different. You'll find suggestions here http://stackoverflow.com/questions/946011/sqlite-add-primary-key – Michael Berkowski Sep 03 '15 at 13:12
  • You probably want it to be unsigned as well as `ALTER TABLE tbl ADD id INT(11) UNSIGNED PRIMARY KEY AUTO_INCREMENT FIRST;` – Ray Mar 01 '16 at 16:31
  • Should I use auto-increment ids when i need to retrieve data based on the id? For instance, how can I use Select * From table_name where id=? when I don't know what is the value of id (as I created it to be auto-increment) ? – Wijay Sharma Jan 21 '18 at 17:42
  • 2
    @WijaySharma If you created the row with auto-increment and must retrieve it by id immediately, MySQL offers `LAST_INSERT_ID()` for that value `SELECT * FROM table_name WHERE id = LAST_INSERT_ID()` and most programming language APIs offer some function/method to return that value in the application code. – Michael Berkowski Jan 24 '18 at 16:06
  • This seems to just hang in Mysql8. – user1717828 Feb 15 '19 at 14:53
  • @user1717828 Interesting - I don't have access to test MySQL8 right now. Is your table really large? MySQL does not usually just hang on something incompatible. It would error out sensibly unless there was an unknown bug. – Michael Berkowski Feb 15 '19 at 14:56
  • @MichaelBerkowski, nope, it's like 140 rows, two columns. I'm brand new to MySQL 8, so trying to poke around and get a feel for the differences. – user1717828 Feb 15 '19 at 14:57
  • @MichaelBerkowski AH wait! I just tried with an empty dummy table and there seems to be no problem. Not sure why it's hanging on the (small) pre-populated table. Please ignore the previous comment. – user1717828 Feb 15 '19 at 14:58
  • Is there a way to indicate a column to use for the default ordering applied before the auto-increment is filled in? Ie. if I have a timestamp column and I want to apply the auto-increment in order using the timestamp? – swinters Sep 21 '21 at 20:27
  • @swinters No, for that you would probably need to first perform an UPDATE query that sets sequential values alongside the timestamp ordering, then add the auto_increment attribute so future inserts maintain the same order. https://stackoverflow.com/questions/6617056/updating-columns-with-a-sequence-number-mysql – Michael Berkowski Sep 21 '21 at 21:52
67

suppose you don't have column for auto increment like id, no, then you can add using following query:

ALTER TABLE table_name ADD id int NOT NULL AUTO_INCREMENT primary key FIRST

If you've column, then alter to auto increment using following query:

 ALTER TABLE table_name MODIFY column_name datatype(length) AUTO_INCREMENT PRIMARY KEY
SirDerpington
  • 11,260
  • 4
  • 49
  • 55
php
  • 4,307
  • 1
  • 24
  • 13
9

In order to make the existing primary key as auto_increment, you may use:

ALTER TABLE table_name MODIFY id INT AUTO_INCREMENT;
KaiserKatze
  • 1,521
  • 2
  • 20
  • 30
Fathima Fasna
  • 91
  • 1
  • 1
7

For those like myself getting a Multiple primary key defined error try:

ALTER TABLE `myTable` ADD COLUMN `id` INT AUTO_INCREMENT UNIQUE FIRST NOT NULL;

On MySQL v5.5.31 this set the id column as the primary key for me and populated each row with an incrementing value.

Community
  • 1
  • 1
reflexiv
  • 1,693
  • 1
  • 21
  • 24
6

Yes, something like this would do it, it might not be the best though. You might wanna make a backup:

$get_query = mysql_query("SELECT `any_field` FROM `your_table`");

$auto_increment_id = 1;

while($row = mysql_fetch_assoc($get_query))
{
  $update_query = mysql_query("UPDATE `your_table` SET `auto_increment_id`=$auto_increment_id WHERE `any_field` = '".$row['any_field']."'");
  $auto_increment_id++;
}

Notice that the the any_field you select must be the same when updating.

Skatox
  • 4,237
  • 12
  • 42
  • 47
Grigor
  • 4,139
  • 10
  • 41
  • 79
3

The easiest and quickest I find is this

ALTER TABLE mydb.mytable 
ADD COLUMN mycolumnname INT NOT NULL AUTO_INCREMENT AFTER updated,
ADD UNIQUE INDEX mycolumnname_UNIQUE (mycolumname ASC);
Infinite Recursion
  • 6,511
  • 28
  • 39
  • 51
Dave
  • 31
  • 1
3

I was able to adapt these instructions take a table with an existing non-increment primary key, and add an incrementing primary key to the table and create a new composite primary key with both the old and new keys as a composite primary key using the following code:

DROP TABLE  IF EXISTS SAKAI_USER_ID_MAP;

CREATE TABLE SAKAI_USER_ID_MAP (
       USER_ID             VARCHAR (99) NOT NULL,
       EID                 VARCHAR (255) NOT NULL,
       PRIMARY KEY (USER_ID)
);

INSERT INTO SAKAI_USER_ID_MAP VALUES ('admin', 'admin');
INSERT INTO SAKAI_USER_ID_MAP VALUES ('postmaster', 'postmaster');

ALTER TABLE  SAKAI_USER_ID_MAP 
  DROP PRIMARY KEY, 
  ADD _USER_ID INT AUTO_INCREMENT NOT NULL FIRST, 
  ADD PRIMARY KEY ( _USER_ID, USER_ID );

When this is done, the _USER_ID field exists and has all number values for the primary key exactly as you would expect. With the "DROP TABLE" at the top, you can run this over and over to experiment with variations.

What I have not been able to get working is the situation where there are incoming FOREIGN KEYs that already point at the USER_ID field. I get this message when I try to do a more complex example with an incoming foreign key from another table.

#1025 - Error on rename of './zap/#sql-da07_6d' to './zap/SAKAI_USER_ID_MAP' (errno: 150)

I am guessing that I need to tear down all foreign keys before doing the ALTER table and then rebuild them afterwards. But for now I wanted to share this solution to a more challenging version of the original question in case others ran into this situation.

drchuck
  • 4,415
  • 3
  • 27
  • 30
1

Export your table, then empty your table, then add field as unique INT, then change it to AUTO_INCREMENT, then import your table again that you exported previously.

David C
  • 19
  • 1
1

You can add a new Primary Key column to an existing table, which can have sequence numbers, using command:

ALTER TABLE mydb.mytable ADD pk_columnName INT IDENTITY 
gofr1
  • 15,741
  • 11
  • 42
  • 52
Nagesh Hugar
  • 43
  • 1
  • 5
  • 1
    `ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IDENTITY' at line 1` – user1717828 Feb 15 '19 at 14:55
1

I was facing the same problem so what I did I dropped the field for the primary key then I recreated it and made sure that it is auto incremental . That worked for me . I hope it helps others

Humphrey
  • 2,659
  • 3
  • 28
  • 38
1

ALTER TABLE tableName MODIFY tableNameID MEDIUMINT NOT NULL AUTO_INCREMENT;

Here tableName is name of your table,

tableName is your column name which is primary has to be modified

MEDIUMINT is a data type of your existing primary key

AUTO_INCREMENT you have to add just auto_increment after not null

It will make that primary key auto_increment......

Hope this is helpful:)

1

Well, you have multiple ways to do this: -if you don't have any data on your table, just drop it and create it again.

Dropping the existing field and creating it again like this

ALTER TABLE test DROP PRIMARY KEY, DROP test_id, ADD test_id int AUTO_INCREMENT NOT NULL FIRST, ADD PRIMARY KEY (test_id);

Or just modify it

ALTER TABLE test MODIFY test_id INT AUTO_INCREMENT NOT NULL, ADD PRIMARY KEY (test_id);
David Buck
  • 3,752
  • 35
  • 31
  • 35
1

No existing primary key


ALTER TABLE `db`.`table` 
ADD COLUMN `id` INT NOT NULL AUTO_INCREMENT FIRST,
ADD PRIMARY KEY (`id`);
;

Table already has an existing primary key'd column

(it will not delete the old primary key column)

ALTER TABLE `db`.`table` 
ADD COLUMN `id` INT NOT NULL AUTO_INCREMENT FIRST,
CHANGE COLUMN `prev_column` `prev_column` VARCHAR(2000) NULL ,
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`);
;

Note: column must be first for auto increment which is why the FIRST command.

Michael Kaufman
  • 312
  • 3
  • 4
0

How to write PHP to ALTER the already existing field (name, in this example) to make it a primary key? W/o, of course, adding any additional 'id' fields to the table..

This a table currently created - Number of Records found: 4 name VARCHAR(20) YES breed VARCHAR(30) YES color VARCHAR(20) YES weight SMALLINT(7) YES

This an end result sought (TABLE DESCRIPTION) -

Number of records found: 4 name VARCHAR(20) NO PRI breed VARCHAR(30) YES color VARCHAR(20) YES weight SMALLINT(7) YES

Instead of getting this -

Number of Records found: 5 id int(11) NO PRI name VARCHAR(20) YES breed VARCHAR(30) YES color VARCHAR(20) YES weight SMALLINT(7) YES

after trying..

$query = "ALTER TABLE racehorses ADD id INT NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (id)";

how to get this? -

Number of records found: 4 name VARCHAR(20) NO PRI breed VARCHAR(30) YES color VARCHAR(20) YES weight SMALLINT(7) YES

i.e. INSERT/ADD.. etc. the primary key INTO the first field record (w/o adding an additional 'id' field, as stated earlier.

De Teague
  • 11
  • 1