Reset autoincrement value in mysql - mysql

I have table having serial no. 1,2,3,4,5 and so on
If I delete the data of for ex. 2 no. then my table shows 1, 3,4,5,6....
I want it should reset the serial no field. Can anybody help me in this?
Pravin

You can renumber the rows of your table by recreating it. That's probably the most foolproof way to do it if the table is small ... 100K rows or smaller.
Something like this would do the trick.
RENAME mytable TO mytable_previous;
CREATE mytable LIKE mytable_previous;
TRUNCATE TABLE mytable;
ALTER TABLE mytable AUTO_INCREMENT = 1;
INSERT INTO mytable
(col, col, col) /* name all cols except autoincrementing */
SELECT (col, col, col) /* same names, same order */
ORDER BY id;
This will allow the INSERT operation to redo the autoincrementing in the same order as the previous table, but without gaps.
BEWARE ... This is probably a bad idea. If the autoincrementing id column is used in other tables as a reference to this table, doing this will wreck your database. Production database tables that have DELETE operations ordinarily just live with gaps in the autoincremented row numbers. Those gaps certainly cause no harm.

Related

SQL Table - How to add a row at the start of an old autoincrement column

I have an existing sql table with 3 columns and 100+ entries/rows. There is an id column with autoincrement.
Now, I want to add 10 new rows at the beginning of the table with id from 1 to 10. But I cannot lose any existing row. So, how do I do it?
One idea that just came to my mind is perhaps I can increase the existing id by adding 10, like 1+10 becomes 11, 25+10 becomes 35, and then I can add rows at the beginning. What will be the script for this IF this is possible?
All you need to do for this is to set the auto_increment for that table to whatever number you need to create space for the new records you want to insert.
For example, if you inserted rows with id's 1-100, you might:
Check the next auto_increment value by running:
select auto_increment as val from information_schema.tables where table_schema='myschema' and table_name='mytable';
Let's assume that value would be 101 (the value that would be used if you inserted a new row). You can "advance" the auto_increment value by running:
alter table myschema.mytable auto_increment = 111;
If you insert a new row like this:
insert into mytable (not_the_id_column) values ('test');
It will get the "next" id of 111. But if you specify id values manually, you are ok in this case as long as you use any value less than 111, so you could insert your desired records like this:
insert into mytable (id, not_the_id_column) values (101, 'test101');
insert into mytable (id, not_the_id_column) values (102, 'test102');
... -- more inserts as needed
Now, you still must take proper precautions when updating PK values, or any value that has dependencies on it (Foreign Key or otherwise), but it is completely legitimate to forcibly advance and/or backfill the id values, as long as the resulting auto_increment value doesn't duplicate one that's already in the table.
I agree with juergen d's comment that you should not do this, but I realize there are situations where this kind of thing must be done.
SELECT MAX(id)-MIN(id)+1 INTO #x FROM theTable;
UPDATE theTable SET id = id + #x;
SELECT MIN(id) INTO #x FROM theTable;
UPDATE theTable SET id = 10 + id - #x;
If the id is the primary key, value collisions within an update can cause MySQL to reject the update. (Hence the pair of updates to avoid such a possibility.)
Edit: Factoring N.B.'s strong objection into this, it would also probably be good to verify the table's next auto-increment value is not going to collide with the updated records after the update is completed. I don't have an appropriate database on hand to verify whether UPDATE statements affect it; and even if they do affect it, you may end up wanting to reduce it so as to not create an unnecessary gap (gaps should ideally not be a problem, but if they are or you are just mildly OCD, it is worth looking into).

Renumbering auto-increment values in rows in MySQL

I have a table with an auto-incrementing primary key. Because I allow my data to be deleted, there are now numerous gaps in the primary keys. For example, if I have row 1, 2 and 3, and 2 gets deleted, I only have rows 1 and 3 left (meaning the number 2 is vacant and empty).
This has proven to give me problems now that I am attempted to conduct a full data migration. So I'm wondering if it's possible at all to simply re-index everything - i.e. run some kind of MySQL UPDATE query such that I update all the rows' primary keys into a smooth, running order.
How do I go about doing this?
I think the easiest way is to create an empty clone of the table and copy all rows from your original one. That way all AUTO_INCREMENT fields are re-assigned.
1) Copy the table:
CREATE TABLE clone_table LIKE original_table;
2) Copy all rows, manually specifying all fields except your AUTO_INCREMENT one (id?) using the INSERT INTO ... SELECT ... syntax:
INSERT INTO clone_table (field1, field2, fieldN)
SELECT field1, field2, fieldN FROM original_table ORDER BY id;
3) Optionally, you can now delete old table and rename the clone:
DROP TABLE original_table;
RENAME TABLE clone_table TO original_table;

Reset the table Auto Increment and make it apply to the table

I have a table with around 10k rows which I've imported. The ID is a significant column to my application, and it has to be ordered. Currently, I got something like: 1,2,3,4,5....5789,9275,9276.....
It jumped from 5789 to 9275. Is there any way I can reset the Auto Increment but also make it apply to the table? which means, now it will start giving them IDS all over again from 1 to 10k
Thanks!
ALTER TABLE <tablename> AUTO_INCREMENT=<new_value>;
Of course you need to fix the high IDs and all references to them manually.
However, why do you care? Does it really matter if there's a hole in the IDs? If yes, you might want to use a separate column that's always set to MAX(col) + 1 instead of an AUTO_INCREMENT column.
You can certainly reset the auto_increment value to be whatever you want by simply issuing this query:
ALTER TABLE <tbl> AUTO_INCREMENT = <n>;
where tbl is your table name and n is the value to start it at. However, if you have existing IDs in that table already, I believe it will simply set the next inserted items ID to be max(id) + 1 of the ID column

How to get rid of duplicate results in a table

I have a table that has some duplicate results. For example:
`person_url` `movie_url`
1 2
1 2
2 3
Would become -->
`person_url` `movie_url`
1 2
2 3
I know how to do it by creating a new table,
create table tmp_credits (select distinct * from name);
However, it is a pretty large table and I have a couple indexes on it which will need to be re-created. How would I do this transformation in place, that is, without creating a new table?
You can add a UNIQUE index over your table's columns using the IGNORE keyword:
ALTER IGNORE TABLE name ADD UNIQUE INDEX (person_url, movie_url);
As stated in the manual:
IGNORE is a MySQL extension to standard SQL. It controls how ALTER TABLE works if there are duplicates on unique keys in the new table or if warnings occur when strict mode is enabled. If IGNORE is not specified, the copy is aborted and rolled back if duplicate-key errors occur. If IGNORE is specified, only the first row is used of rows with duplicates on a unique key. The other conflicting rows are deleted. Incorrect values are truncated to the closest matching acceptable value.
This will also prevent duplicates from being added in the future.
`create table temp
(col1 varchar(20),col2 varchar(20));
INSERT INTO temp VALUES
('1','one'),('2','two'),('2','two');
`select col1,col2 from temp
union
select col1,col2 from temp;
`
Have you considered just putting a semantic layer/view on top of the table that de-dups?
select person_url, movie_url
from name
group by person_url, movie_url

Duplicating rows in a mysql table without enumerating fields

This mysql table has an autoincrement field. I want to duplicate some rows. I thought I will use a temporary table:
CREATE TEMPORARY TABLE tmptab SELECT * FROM mytab WHERE somecondition = 1;
Before copying the data back to mytab I can now do some updates in tmptab.
UPDATE tmptab ... /* some updates */;
Because mytab has an autoincrement field I cannot simply copy the contents of tmptab to mytab. One solution would be to enumarate fields (and omit the autoincrement field).
I am looking for a solution without enumerating fields. This has advantages, for instance when fields will be added later.
I thougth I could erase the autoincrement field in tmptab (removing the autoincrement column) and then use a query similar to this one:
INSERT INTO mytab SELECT * FROM tmptab;
Would this work? The autoincrement field in mytab should be set correctly. Or is there a better way to do it?
I thougth I could erase the autoindex field in tmptab (removing the autoindex column) and then use a query similar to this one
You need to use a command like this:
UPDATE tmptab SET key_column=NULL
When you insert NULLs back into the original table, it will generate new auto_increment ids.
You might need to add a command to drop the primary key index on the temp table for this to work.