update unique indexed column in mysql - mysql

I have a unique indexed column A with integer in it. I'd like it to increment by 1, in Oracle I do: update table set A=A+1 and it worked. But in mySQL, it give me the following error:
- MySQL Database Error: Duplicate entry '2' for key 1. I have three rows in the table with value: 1, 2 and 3 individually. I know why it gives me this error. But how do I solve this problem? Thanks.

You receive this error because your UPDATE TABLE SET A = A + 1, when updating the first ROW from 1 to 2 (1+1), it will get conflict with your second ROW, because there already is a ROW with ID = 2.
You have to do it descender from the last ROW to the first, do you have to alter your query to this:
UPDATE TABLE SET ID = ID + 1 ORDER By ID DESC;
The DESC clause will make the updates from the bottom of your table, so it won't find any duplicate ID in his path...

You can do this using an ORDER BY:
update table
set A=A+1
order by A desc

Related

Change MySQL query execution order

I want to put a entry in the database with id of 2. In order to do that I'm moving all records having more than 2 to id + 1.
UPDATE
`pedo_meta`
SET
`id` = `id` + 1
WHERE
`id` > 1;
Because id is a primary key. This query is failing saying :
#1062 - Duplicate entry '3' for key 'PRIMARY'. I know this is happening because query execution starts from top to bottom and when the query tries to make a the column having id 2 to id 3, a duplicate entry error occurs because id 3 column already exists.
I believe this problem can be solved if we reverse the order of execution. So the query starts by making id 537 to 538 then 536 to 537 and so on. So is there any to reverse the order of execution for a query in MySQL?
You can use ORDER BY on the UPDATE statement to affect the order the rows are updated:
If the ORDER BY clause is specified, the rows are updated in the order that is specified.
source: https://dev.mysql.com/doc/refman/8.0/en/update.html
So you can use the following UPDATE statement:
UPDATE `pedo_meta`
SET `id` = `id` + 1
WHERE `id` > 1
ORDER BY `id` DESC;
demo on dbfiddle.uk
Note: If you want to change the sort order of items you shouldn't use the ID column. You can add an additional numeric column to define a sort order. The ID column should only be use to identify a record in the table.
Here is a simple algorithm to accomplish that fast:
1. create a new column new_id
2. set new_id = id + 1
3. update id and set it to be id = new_id
4. remove column new_id when you are done
P.S. IF you want to sort your items after id is better to create a new column sort_order which can be updated extremely fast...

mysql update id value from another table + current id

I have 2 tables. lets say Table and BackupTable
And i want to Update the id of Table with the last id from BackupTable.
because BackupTable holds all the data of Table. And table is being deleted after the data was inserted and then deleted.
This is what i have as a command.
update Table set id = CONCAT((SELECT id FROM BackupTable
ORDER BY BackupTable.id ASC) + id);
it gives me an error:
#1242 - Subquery returns more than 1 row
and from there i know how to add the data from Table to Backuptable.
nevermind...so stupid of me :)) i was selecting all the id's from that table
this is it.... i had to select the last inserted id.
update phubChannelRank set id = CONCAT((SELECT max(id) FROM ArchiveTheSeeker.phubChannelRank) + id);

How can I update an existing record to have a new auto_increment id in MySQL?

I have a table with primary key (its name is "id") defined as auto_increment. I use NULL in INSERT statements to "fill" the id value. It works, of course. However now I need to "move" an existing record to a new primary key value (the next available, the value is not so much important, but it must be a new one, and the last one if ordered by id). How can I do it in an "elegant" way? Since the "use NULL at INSERT" does not work too much with UPDATE:
update idtest set id=NULL where id=1;
This simply makes the id of the record zero. I would expect to do the same thing as with INSERT, but it seems my idea was incorrect.
Of course I can use "INSERT ... SELECT" statement, then a DELETE on the old one, or I can use something like MAX(id) + 1 to UPDATE the id of the old record in one step, etc, but I am curious if there is a finer solution.
Also, the MAX(id) solution doesn't seem to work either by the way:
mysql> update idtest set id=max(id)+1 where id=3;
ERROR 1111 (HY000): Invalid use of group function
mysql> update idtest set id=(select max(id)+1 from idtest) where id=3;
ERROR 1093 (HY000): You can't specify target table 'idtest' for update in FROM clause
This is the way I believe:
UPDATE users SET id = (SELECT `AUTO_INCREMENT`
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'test'
AND TABLE_NAME = 'users') WHERE id = 2;
select * from users;
I used by own tables substitute yours.
test is database name, users is table name and id is AUTO_INCREMENT in my case.
EDIT: My Query above works perfect but its side effects are somewhat 'dangerous', upon next insert as AUTO_INCREMENT value will collide with this recently updated record so just next single insert will fail. To avoid that case I've modified above query to a transaction:
START transaction;
UPDATE users SET id = (SELECT `AUTO_INCREMENT`
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'test'
AND TABLE_NAME = 'users') WHERE id = 2;
#renew auto increment to avoid duplicate warning on next insert
INSERT IGNORE INTO users(username) values ('');
COMMIT
Hope this will help someone if not OP.
The way you are trying to update same table is wrong but you can use join on same table
update idtest t
join (select id +1 as id
from idtest order by id desc
limit 1) t1
set t.id=t1.id
where t.id=3;
or
update idtest t
join (select max(id) +1 as id
from idtest ) t1
set t.id=t1.id
where t.id=3;
You can use the REPLACE INTO clause to do the trick.
From the manual:
REPLACE works exactly like INSERT, except that if an old row in the table has the same value as a new row for a PRIMARY KEY or a UNIQUE index, the old row is deleted before the new row is inserted. See Section 13.2.5, "INSERT Syntax".
EDIT
My mistake (in the comments) that you have to have two unique constraint to achieve this:
When you use the auto_increment value to REPLACE the record, the record will be replaced with the give ID and will not change (however the AI value will increment).
You have to exclude the AI column from the query. You can do that if you have one more UQ constraint.
Check this SQLFiddle demo: http://sqlfiddle.com/#!2/1a702e
The first query will replace all the records (but the id's value will not change).
The second one will replace it too, and the new AI value will be used. (Please note, that the second query does not contain the id column, and there is a UQ constraint on the some column).
You can notice, that the second query uses higher AI values than it is excepted: this is because the first replace incremented the AI value.
If you do not have two unique keys (one for the AI and one for another columns), the REPLACE statement will work as a normal INSERT statement!
(Ofcourse you can change one of the UNIQUE KEYs with a PRIMARY KEY)

#1136 - Column count doesn't match value count at row 1

I am trying to insert ID field from one table to another using below query:
INSERT INTO `srikprag_db`.`acbalance`
SELECT `id` FROM `srikprag_mlm`.`member_table`
Error is showing:
#1136 - Column count doesn't match value count at row 1
What is the reason for this error?
You did not define the destination column on where the values from the SELECT statement will be saved, eg.
INSERT INTO srikprag_db.acbalance (ID) -- <<== destination column
SELECT id
FROM srikprag_mlm.member_table
probably you want to manipulate records across database.
The problem is with your query you are not assigning any value to the column. You have 1 column with zero value.
SELECT `id` FROM `srikprag_mlm`.`member_table`
returns a result set with only 1 column (id).
The acbalance table probably has more than 1 column.

Autoincrement manually a column MySQL

I have a table with columns:
[id,name,public_id]
actually the table contains
[1,john,0]
[2,sara,0]
[3,jack,0]
.....
I want to change the third column to 1050,1051,1052....
[1,john,1050]
[2,sara,1051]
[3,jack,1052]
.....
How can I make that update?
Some considerations: The public id must be over 1049 and must be consecutive. For example for 100 rows the public_id must be [1050....1149]
Thanks in advance
You can do an update like this:
UPDATE table SET public_id = id + 1049
With this, you are using the ID, and adding 1049 to it to get the result you need
Assuming your table's name is TEST_TABLE, this MySQL syntax will update PUBLIC_ID with consecutive values starting from 1500 (and in order of ID):
REPLACE INTO TEST_TABLE
SELECT TEST_TABLE.ID, TEST_TABLE.NAME, #ROWNUM := #ROWNUM + 1
FROM
TEST_TABLE,
(SELECT #rownum := 1499) R
ORDER BY ID
In plain English:
For each row, figure out its order when data is sorted by ID. Call this order "ROWNUM".
Put ROWNUM (+ starting offset) back to the table instead of the original PUBLIC_ID.
WARNING: According to MySQL documentation, REPLACE will actually delete a duplicated row before inserting it again (instead of just updating modified fields), which my be an issue in the presence of foreign keys.
(Not sure about SQLite, but I'm guessing you could employ a similar general idea.)