I have an id i.e primary key and auto increment. Is there any query to update my existing id and make my id start from 1 and next id 2 and so on..
For example
id name
3 ABC
5 XYZ
9 PQR
NOTE: id is already primary and auto increment and I don't want truncate my id.
if possible i want to get
id name
1 ABC
2 XYZ
3 PQR
ALTER TABLE table AUTO_INCREMENT = 1; is not my solution.
Thanks
Of course there is a way:
set #counter = 0;
update table_name
set id = (#counter := #counter + 1);
EDIT
To avoid problem with duplicate keys you can run something like this before to temporary change current ids to negative equivalents:
update table_name
set id = 0 - id;
Is there any query to update my existing id and make my id start from 1 and next id 2 and so on
What you can do is transfer the content of your table to another table. Reset the auto increment counter, insert your data back into the original table but let MySQL assign the primary key.
Assuming your table name is mytable You do it like this:
CREATE TABLE mytable_tmp select * from mytable;
TRUNCATE TABLE mytable;
ALTER TABLE mytable AUTO_INCREMENT = 1;
INSERT INTO mytable(name) SELECT name FROM mytable_tmp ORDER BY id;
DROP TABLE mytable_tmp;
In my opinion you shouldn't mess with auto_increment columns at all. Let them be as they are. Their only job is to identify a row uniquely. If you want a nice serial number use another column (make it unique if you wish)!
You will always run into trouble and there will always happen things, that mess with your nice 1, 2, 3, ... sequence. A transaction gets rolled back? Boom, your sequence is 1, 2, 3, 5, ... instead of your intended 1, 2, 3, 4, ...
This can also be a very heavy operation. An auto_increment column is always also a primary key. Every other index on this table includes the primary key. Every time you reset your auto_increments, every index on this table is rewritten.
So my advice is, don't mess with auto_increments.
This query will work for your scenario:
ALTER TABLE tablename DROP id
ALTER TABLE tablename ADD id INT NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (id), AUTO_INCREMENT=1
Related
I have a database in phpmyadmin and there is one thing I don't understand with
the auto_increment. I have several tables with each id auto_increment. If I remove a data with the id-number of 3 for example and then add a new data why does it
print out id-number 4. I just deleted the id 3 shouldn't it print out id 3 again?
Preview
After each insert to the table, the autoincrement value is incremented by 1. So when you add row with ID 3, then autoincrement will be 4. Its not changed, when you delete some row(s).
To change autoincrement value (ID of the next inserted row), use this query:
ALTER TABLE table_name AUTO_INCREMENT = 3
Here is the documentation:
http://www.w3schools.com/sql/sql_autoincrement.asp
https://dev.mysql.com/doc/refman/5.6/en/example-auto-increment.html
I have a table which has a structure like as below.
create table test_table (id INT NOT NUll AUTO_INCREMENT
, name varchar(100),
primary key (id))ENGINE=INNODB
Select * from test_table;
id name
1 a
2 b
3 c
Now I want to increment the id by a number lets say 2
So the final results should be
Select * from test_table;
id name
3 a
4 b
5 c
The way I can do it is, first remove the PK and auto increment and then
update the table:
update test_table set id=id+2;
The other way is to make a temp table with out PK and auto increment and then
extract the result to the main table.
Is there any other way to do this without destroying the table structure ?
I am using MYSQL.
In your example, you need to remove the PK first to allow (temporary) duplicate id's during the course of the update.
To avoid duplicates, you must perform an ordered update:
UPDATE test_table SET id = id + 2 ORDER BY id DESC;
This will update records with largest value of id first, hence avoiding collision.
Obviously, if you want to decrement the values of id, then use "ORDER BY id ASC".
Here is the query to update the tables in SQL :- Its generic
UPDATE table_name SET column1=value, column2=value2,WHERE some_column=some_value;
Please follow the link for more information
Update Query
Thanks,
Pavan
How can I insert values into a table (MySQL) in the following manner:
On all the rows of a table, in order of ID column (PK), insert incrementing number in column 'num'?
For example if the table had 3 rows , with Ids 1,5,2, I want ID 1 to get num=1, ID 2 to get num=2 and ID 5 to get num=3.
EDIT
I will explain why I (think I) need this:
I am trying to split a column off a table into a separate table with a 1-to-1 relation. I thought I would get all the values in order of ID and insert them into the new table, with an auto-incrementing PK. then I know that, in order of ID, the values for the new reference column in the original table will be auto-incrementing numbers. So I want to insert them in that order. I hope this is clear.
i am currently not in front of sql database engine and cannot therefore submit fully verified sql code. however if your num field is not an autoincrement field than do something like this:
CREATE TEMPORARY TABLE temp_table_x (
num int auto_increment primary key,
reference_id int
);
INSERT temp_table_x (reference_id)
SELECT id FROM source_table ORDER BY id;
UPDATE source_table st
SET st.num = x.num
FROM temp_table_x x
WHERE reference_id = id;
As long as the num field is an autoincrement field it should be as simple as:
INSERT INTO
yourTable (
field1,
field2,
field3,
etc
)
SELECT
field1,
field2,
field3
FROM
yourSourceTable
ORDER BY
originalIdField
I would NOT make a field that references a column in another table an auto-increment column.
Even if the column that it references is an auto-increment, I wouldn't make the column auto-increment. It will be difficult to keep the columns in sync. If an insert is rolled back in one table but not the other, you'll be out of sync until you reset the auto_increment value.
If it's a 1 to 1 relationship, feel free to make the column a primary key. That way it will be ordered by the column, and it will ensure unique values. However, if any two columns must match, they should not both be auto-increment, though, they should be of the same type (eg. INTEGER).
For example, here's our original table, where the first column is an auto-increment integer column:
id customer_name email_address
---------------------------
1 jsmith jsmith#aol.com
2 bwilliams bwilliams#aol.com
If you wanted to split the email_address off to its own table, in a 1 to 1 relationship:
id email_address
---------------------------
1 jsmith#aol.com
2 bwilliams#aol.com
I would make the first column an integer field and make it the primary key, but it would NOT be an auto-increment column.
To insert values into such a table, you could simply do this:
INSERT INTO table2
(id, email_address)
SELECT id, email_address
FROM table1
ORDER BY id
I found the answer. It is very simple:
SET #c=0;
UPDATE myTable SET num = (#c:=#c+1) ORDER BY id
is there a way in SQL to create the constraint that a column has to be unique, if a specific column has a specific value?
Example: the rows are not really deleted, but marked as 'deleted' in the database. And within the 'not-deleted' rows, ValueA has to be unique:
ID ValueA ValueB Deleted
-----------------------------------------------------
1 'foo' 10 0
2 'bar' 20 0
3 'bar' 30 1
4 'bar' 40 1
5 'foo' 50 0 --NOT ALLOWED
I thought of something like a CHECK constraint, however I don't know how to do this.
with SQL92 this is not possible, may be you could implement something with a trigger
Can you change the design a little bit?
It seems to me that you have a list of "thingies". For each ValueA, there's a single active "thingy" at any one time. This can best be modeled as follows:
Remove ValueA and Deleted from your main Thingies table.
Create a new table ActiveThingies with columns ValueA and ID. Protect this table by making ValueA a unique or primary key. (You may also need to make ID unique as well depending on whether a single ID can represent more than 1 ValueA).
Now, use the ActiveThingies table to control which record is current at any time. To change the active (non-deleted) record for "foo", update it's ID column in ActiveThingies.
To get your list of non-deleted items join the two tables.
With this design, however, you will lose the ability to remember the ValueA for "deleted" "thingies". If you need to remember those values, you will also need to include the ValueA column in Thingies.
There is workaround this problem - create another column deleted_on
deleted_on timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
and make unique key on both ValueA and deleted_on
UNIQUE KEY not_deleted (ValueA, deleted_on)
When soft deleting a record insert NOW() for value of deleted_on
MySQL ignores CHECK constraints, so you cannot do this in MySQL as you might in another database.
Here is a hack. Unique constraint on valueA + deleted. When deleting rows you cannot use just 1, they must be 1, 2, 3...
This at least lets you do it server-side in MySQL, but introduces a step. When marking a row for deletion, you have to first go find the max(deleted), add 1, and plug that value in when marking for deletion.
Split your table into two tables: One which has a UNIQUE constraint on ValueA and one that doesn't. Use a view+triggers to combine the two tables. Something like:
CREATE TABLE _Active (
ID INTEGER,
ValueA VARCHAR(255) UNIQUE,
ValueB INTEGER
);
CREATE TABLE _Deleted (
ID INTEGER,
ValueA VARCHAR(255), /* NOT unique! */
ValueB INTEGER
);
CREATE VIEW Thingies AS
SELECT ID, ValueA, ValueB, 0 AS Deleted FROM _Active
UNION ALL
SELECT ID, ValueA, ValueB, 1 AS Deleted FROM _Deleted;
CREATE TRIGGER _trg_ii_Thingies_Active
INSTEAD OF INSERT ON Thingies
FOR EACH ROW WHEN NOT NEW.Deleted
BEGIN
INSERT INTO _Active(ID, ValueA, ValueB)
VALUES (NEW.ID, NEW.ValueA, NEW.ValueB);
END;
CREATE TRIGGER _trg_ii_Thingies_Deleted
INSTEAD OF INSERT ON Thingies
FOR EACH ROW WHEN NEW.Deleted
BEGIN
INSERT INTO _Deleted(ID, ValueA, ValueB)
VALUES (NEW.ID, NEW.ValueA, NEW.ValueB);
END;
/* Add triggers for DELETE and UPDATE as appropriate */
(I'm not sure about the CREATE TRIGGER syntax, but you know what I mean.)
I want to know if I can repopulate the autoincrement value in mysql.
Because, I have records that look similar:
ID Name
1 POP
3 OLO
12 lku
Basically , I want a way to update the ID to this
ID Name
1 POP
2 OLO
3 lku
Is there any way to do this in mysql?
Thanks.
It's not best practice to fiddle your primary keys - better to let your DB handle it itself. There can be issues if, in between the UPDATE and ALTER, another record is added. Because of this, you must LOCK the table, which might hang other queries and spike load on a busy production server.
LOCK TABLES table WRITE
UPDATE table SET id=3 WHERE id=12;
ALTER TABLE table AUTO_INCREMENT=4;
UNLOCK TABLES
OR - for thousands of rows (with no foriegn key dependencies):
CREATE TEMPORARY TABLE nameTemp( name varchar(128) not null )
INSERT INTO name SELECT name FROM firstTable
TRUNCATE firstTable
INSERT INTO firstTable SELECT name FROM nameTemp
The latter method will only work where you have no foreign keys. If you do, you'll require a lookup table.
CREATE TEMPORARY TABLE lookup( newId INTEGER AUTO_INCREMENT, oldId INTEGER, PRIMARY KEY newId( newId ) );
INSERT INTO lookup (oldId) SELECT id FROM firstTable
[do temp table queries above]
You now have a lookup table with the old to new ids which you can use to update the foreign key dependencies on your other tables (on a test server!)
Changing the primary key is a very bad idea as it endangers your referential integrity (what if another table uses the id without having a foreign key with proper "on change"?).
If you really, really have to do it and don't care about bad side-effects:
Create a second table with identical structure
INSERT INTO new_table (id, [other fields]) SELECT NULL, [other fields] FROM old_table;
DROP old_table;
RENAME new_table old_table;
Warning:
This will damage every other table that has foreign keys on this table (but if you had such then you wouldn't be doing this anyways).
You may want to try something like...
Create Temporary table MyBackup
( ID as your autoincrement,
OldID as Int for backlinking/retention,
RestOfFields as their type )
insert into MyBackup
( OldID
RestOfFields )
select
ID as OldID,
RestOfFields
from
YourOriginalTable
order by
ID (this is your original ID)
Then you'll have a new table with an autoincrement with new IDs assigned, yet have a full copy of their original ID. Then, you can do correlated updates against other tables and set the ID = ID where ID = OldID. By keeping your insert via order by the original ID, it will keep the numbers from replacing out of sequence.. Ex: if your table was orderd as
Old ID = 3, new ID = 1
Old ID = 1, new ID = 3
Old ID = 12, new ID = 2
Your old 3's will become 1's, then the 1's would become 3's, and 12's become 2's
Old ID = 1, new ID = 1
Old ID = 3, new ID = 2
Old ID = 12, new ID = 3
your 3's won't overwrite the higher number, and the 12's won't conflict with the 3's since the threes were already lowered to 2's.