How to update without altering the structure of table - mysql

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

Related

How to update id set from 1?

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

How do I increase ID value for specific MySQL rows by 1?

I have a column in a MySQL table which enters an auto-increment ID as new rows are added. Data from the MySQL table is pulled into an HTML table and the rows of the HTML table are sorted by the ID column. Normally this works fine for my purposes, but I now need to enter a row with a lower ID than the current auto-increment value, so that it appears further down the table.
So, I am wondering if there is a way, using a MySQL statement to add 1 to the ID values for a specific range of rows, e.g. add 1 to rows 800-850, so that they would now be 801-851, and then I could manually insert a new row with an ID value of 800.
You need to let the auto-incrementation working alone and create a new field table_id in your table to set the id number you want.
Reset table id is never a good idea : for example, don't forget all foreign keys linked on your table id.
To increment 1 to your specific id number, it would be :
UPDATE your_table SET table_id = table_id + 1 WHERE table_id BETWEEN 800 AND 850
update [yourtablename]
set [youridfieldoftable]=[youridfieldoftable] + 1
where [youridfieldoftable] >= 800
and [youridfieldoftable] <= 850
Be sure to substitute the table and field names with the correct ones. The field is the same four times.
In order to avoid the error
Duplicate entry x for key 'PRIMARY'
add the ORDER BY clause in the suggested query
UPDATE
your_table
SET
table_id = table_id + 1
WHERE
table_id BETWEEN 800 AND 850
ORDER BY
table_id DESC

Inserting into table in order

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

Duplicate Entries in DB

I have a huge table of products but there are lot of duplicate entries. The table has more than10 Thousand entries and I want to remove the duplicate entries in it without manually finding and deleting it. Please let me know if you can provide me a solution for this
You could use SELECT DISTINCT INTO TempTable, drop the original table, and then rename the temp one.
You should also add primary and unique keys to avoid this sort of thing in the future.
for full row duplicates try this.
select distinct * into mytable_tmp from mytable
drop table mytable
alter table mytable_tmp rename mytable
Seems the below statements will help you in resolving your requirements.
if the table(foo) has primary key field
First step
store key values in temporary table, give your unique conditions in group by clause
if you want to delete the duplicate email id, give email id in group by clause and give the primary key name in
select clause like either min(primarykey) or max(primarykey)
CREATE TEMPORARY TABLE temptable AS SELECT min( primarykey ) FROM foo GROUP BY uniquefields;
Second step
call the below delete statement and give the table name and primarykey columns
DELETE FROM foo WHERE primarykey NOT IN (SELECT * FROM temptable );
execute both the query combined in your query analyser or db tool.
If the table(foo) doesn't have a primary key filed
step 1
CREATE TABLE temp_table AS SELECT * FROM foo GROUP BY field or fileds;
step 2
DELETE FROM foo;
step 3
INSERT INTO foo select * from temp_table;
There are different solutions to remove duplicate rows and it fully depends upon your scenario to make use of one from them. The simplest method is to alter the table making the Unique Index on Product Name field:
alter ignore table products add unique index `unique_index` (product_name);
You can remove the index after getting all the duplicate rows deleted:
alter table products drop index `unique_index`;
Please let me know if this resolves the issue. If not I can give you alternate solutions for that.
You can add more than one column to a group by. I.E.
SELECT * from tableName GROUP BY prod_name HAVING count(prod_name) > 1
That will show the unique products. You can write it dump it to new table and drop the existing one.

MySQL, two columns both set to the primary key

For the sake of simplicity lets say I have a table with 3 columns; id, parent_id and name. In this table id is my auto-incrementing primary key. I want to group multiple names together in this table, to do this all names in a group will share the same parent_id. If I am inserting the first name in the group I want the id=parent_id, if i am inserting another name I want to specify a specific parent_id to place that name into a specific group. It would be nice if I could define a default for that column to be the same as the id, if I specify a value for parent_id in the insert query then I would like it to use that value. I know you can set a default to be a specific static value, but can you specify the default to be the same as that row's auto-incrementing primary key? Perhaps this is a job for a trigger or stored procedure?
(I know I could obtain the primary key generated by the last insert and then update the table, but that's 2 quires I'd rather not burn.)
Thanks!
This is a job of a trigger!
CREATE TRIGGER NAME1 AFTER INSERT ON TABLE1
BEGIN
UPDATE TABLE1 SET parent_id = id WHERE (parent_id IS NULL OR parent_id = '');
END;
INSERT INTO TABLE1 (id,parent_id) VALUES (null,null); -- parent_id will be equal to id
INSERT INTO TABLE1 (id,parent_id) VALUES (null,'1'); -- parent_id will be 1
INSERT INTO TABLE1 (id,parent_id) VALUES (null,'2'); -- parent_id will be 2