I have about 1000 entries in my database:
id name
0 elephant
0 snake
0 monkey
....
I want no to change all ids afterwards. So that it looks like this:
id name
1 elephant
2 snake
3 monkey
....
How can I achieve this with SQL?
One option would be to leverage an auto increment column, in a new table, then insert your previous content into that table. First, create a new table with an auto increment id:
CREATE TABLE newTable (
id INT AUTO INCREMENT NOT NULL,
name varchar(255)
);
Now insert your old table into the new one:
INSERT INTO newTable (name)
SELECT name FROM oldTable; -- you may select multiple columns here
Two potentials drawbacks here are that now you have an old table that might need to be deleted, and also the order assigned to the names would be arbitrary. But in absence of logic for how to assign the IDs, this approach seems reasonable.
Here is the step by step solution for your problem, hopefully, resolve your issue.
mysql> create table dt1(id int,name varchar(20));
mysql> insert into dt1 values(0,'elephant');
mysql> insert into dt1 values(0,'snake');
mysql> insert into dt1 values(0,'monkey');
mysql> select * from dt1;
+------+----------+
| id | name |
+------+----------+
| 0 | elephant |
| 0 | snake |
| 0 | monkey |
mysql> update dt1 x join (select id,name,#r:=#r+1 as new_id from dt1,(select #r := 0)r) y on (x.name = y.name) set x.id = y.new_id;
Rows matched: 3 Changed: 3 Warnings: 0
mysql> select * from dt1;
+------+----------+
| id | name |
+------+----------+
| 1 | elephant |
| 2 | snake |
| 3 | monkey |
Related
Sorry if my question is inappropriate but I need the answer for one of my project
Actually, I want to insert multiple records from table1 to table2 of MySql. But before inserting records in table2, I need to check if any record already exists in table2, and If any single record exists then skip that record and insert the remaining ones.
For Example: I want to insert record 101 & 102 in table2 from table1 but if record 101 already exists in table2 then skip 101 and insert 102.
This is my code to insert record from table1 to table2
INSERT INTO table2 (owner_id, month,date,medium, monthly_rent, tax_deduction, final_payment)
SELECT id, 'sep2020','2020/10/05',medium, monthly_rent, tax_deduction, final_payment
FROM table1
WHERE table1.id =('100','101')
Since you have a primary key on id you could use INSERT IGNORE..https://dev.mysql.com/doc/refman/8.0/en/insert.html which will throw a warning if a duplicate key is detected and won't add a new row. for example
DROP TABLE IF EXISTS T,T1;
CREATE TABLE T (ID INT, VAL INT);
CREATE TABLE T1 (ID INT PRIMARY KEY,VAL INT);
INSERT INTO T VALUES (101,10),(102,20),(103,30);
INSERT IGNORE INTO T1
SELECT ID,VAL
FROM T;
UPDATE T SET VAL = 50 WHERE ID = 101;
INSERT IGNORE INTO T1
SELECT ID,VAL
FROM T;
mysql> SELECT * FROM T;
+------+------+
| ID | VAL |
+------+------+
| 101 | 50 |
| 102 | 20 |
| 103 | 30 |
+------+------+
3 rows in set (0.05 sec)
mysql> SELECT * FROM T1;
+-----+------+
| ID | VAL |
+-----+------+
| 101 | 10 |
| 102 | 20 |
| 103 | 30 |
+-----+------+
3 rows in set (0.00 sec)
It seems that you want to add a row to table2 every time an new row is added to table1 so it may be worth considering a trigger to do the job. https://dev.mysql.com/doc/refman/8.0/en/triggers.html
So i have the following table
but when i run the following command:
"INSERT INTO default_db.loader_messages (confirmation_secure_radio_button_message) VALUES ('$confirmmessagevalue1')";
it adds a new row, but empties the loader_message1 column as you can see above.
please tell me how do i keep the current data in the loader_message1 column as well as add a new row ?
If you can change from an insert..values to insert..select then you could
drop table if exists t;
create table t (id int auto_increment primary key,col1 varchar(10),col2 varchar(10));
insert into t (col1) values ('col1');
insert into t (col1,col2)
select col1,'aaa'
from t where id = (select max(id) from t)
;
insert into t (col1) values ('xxx');
insert into t (col1,col2)
select col1,'bbb'
from t where id = (select max(id) from t)
;
select * from t;
+----+------+------+
| id | col1 | col2 |
+----+------+------+
| 1 | col1 | NULL |
| 2 | col1 | aaa |
| 3 | xxx | NULL |
| 4 | xxx | bbb |
+----+------+------+
4 rows in set (0.02 sec)
if this is not a possibility for you then consider capturing in your front end before inserting or inserting in a procedure and fill down after the insert using an update.
I mentioned that it is a poor design to replicate column value to multiple rows.
Still...you shall
select loader_message1 from dbname where yourcondition;
get the mysqli result into $row and then using
$row['loader_message1'] or $row[0]
in the insert like
insert... (fld1, fld2) values (value1, value2)
I am not able to reset the auto_increment value even after making changes after referring to other post
I tried :
ALTER TABLE tablename AUTO_INCREMENT = 101
ALTER TABLE users AUTO_INCREMENT=1001;
or if you haven't already added an id column, also add it
ALTER TABLE users ADD id INT UNSIGNED NOT NULL AUTO_INCREMENT,
ADD INDEX (id);
But still not working
Check this :
mysql> ALTER TABLE table2 ADD id INT UNSIGNED NOT NULL AUTO_INCREMENT,
-> ADD INDEX (id);
Query OK, 5 rows affected (0.17 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql> select * from table2;
+----------------+----+
| name | id |
+----------------+----+
| Abhilash Gupta | 1 |
| John | 2 |
| Peter | 3 |
| Clarke | 4 |
| Virat | 5 |
+----------------+----+
5 rows in set (0.00 sec)
mysql> ALTER TABLE table2 AUTO_INCREMENT=101;
Query OK, 5 rows affected (0.25 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql> select * from table2;
+----------------+----+
| name | id |
+----------------+----+
| Abhilash Gupta | 1 |
| John | 2 |
| Peter | 3 |
| Clarke | 4 |
| Virat | 5 |
+----------------+----+
5 rows in set (0.00 sec)
mysql>
I want the value of id to start from 101.
Thanks in advance
If you want to change the existing IDs to start from 101, use:
UPDATE table2
SET id = id + 100;
The auto_increment setting is used for the ID of the next row to be added, it has no effect on existing rows.
Follow this link for reference to AUTO INCREMENT
Now what you are doing is i think correct, but the changes are not reflected because you did not try to enter a new row to the database. Alter command changes the AUTO INCREMENTS value but that will only be reflected in the next insert to the database. It will not affect the data that is already present in the TABLE. Try entering a new row to the DB and check if the ID Value changes.
If not then post the output after entering that row.
This is how it should be written
cur.execute('''ALTER TABLE tablename AUTO_INCREMENT=0''')
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How can I remove duplicate rows?
Remove duplicates using only a MySQL query?
I have a large table with ~14M entries. The table type is MyISAM ans not InnoDB.
Unfortunately, I have some duplicate entries in this table that I found with the following request :
SELECT device_serial, temp, tstamp, COUNT(*) c FROM up_logs GROUP BY device_serial, temp, tstamp HAVING c > 1
To avoid these duplicates in the future, I want to convert my current index to a unique constraint using SQL request :
ALTER TABLE up_logs DROP INDEX UK_UP_LOGS_TSTAMP_DEVICE_SERIAL,
ALTER TABLE up_logs ADD INDEX UK_UP_LOGS_TSTAMP_DEVICE_SERIAL ( `tstamp` , `device_serial` )
But before that, I need to clean up my duplicates!
My question is : How can I keep only one entry of my duplicated entries? Keep in mind that my table contain 14M entries, so I would like avoid loops if it is possible.
Any comments are welcome!
Creating a new unique key on the over columns you need to have as uniques will automatically clean the table of any duplicates.
ALTER IGNORE TABLE `table_name`
ADD UNIQUE KEY `key_name`(`column_1`,`column_2`);
The IGNORE part does not allow the script to terminate after the first error occurs. And the default behavior is to delete the duplicates.
Since MySQL allows Subqueries in update/delete statements, but not if they refer to the table you want to update, I´d create a copy of the original table first. Then:
DELETE FROM original_table
WHERE id NOT IN(
SELECT id FROM copy_table
GROUP BY column1, column2, ...
);
But I could imagine that copying a table with 14M entries takes some time... selecting the items to keep when copying might make it faster:
INSERT INTO copy_table
SELECT * FROM original_table
GROUP BY column1, column2, ...;
and then
DELETE FROM original_table
WHERE id IN(
SELECT id FROM copy_table
);
It was some time since I used MySQL and SQL in general last time, so I´m quite sure that there is something with better performance - but this should work ;)
This is how you can delete duplicate rows... I'll write you my example and you'll need to apply to your code. I have Actors table with ID and I want to delete the rows with repeated first_name
mysql> select actor_id, first_name from actor_2;
+----------+-------------+
| actor_id | first_name |
+----------+-------------+
| 1 | PENELOPE |
| 2 | NICK |
| 3 | ED |
....
| 199 | JULIA |
| 200 | THORA |
+----------+-------------+
200 rows in set (0.00 sec)
-Now I use a Variable called #a to get the ID if the next row have the same first_name(repeated, null if it's not).
mysql> select if(first_name=#a,actor_id,null) as first_names,#a:=first_name from actor_2 order by first_name;
+---------------+----------------+
| first_names | #a:=first_name |
+---------------+----------------+
| NULL | ADAM |
| 71 | ADAM |
| NULL | AL |
| NULL | ALAN |
| NULL | ALBERT |
| 125 | ALBERT |
| NULL | ALEC |
| NULL | ANGELA |
| 144 | ANGELA |
...
| NULL | WILL |
| NULL | WILLIAM |
| NULL | WOODY |
| 28 | WOODY |
| NULL | ZERO |
+---------------+----------------+
200 rows in set (0.00 sec)
-Now we can get only duplicates ID:
mysql> select first_names from (select if(first_name=#a,actor_id,null) as first_names,#a:=first_name from actor_2 order by first_name) as t1;
+-------------+
| first_names |
+-------------+
| NULL |
| 71 |
| NULL |
...
| 28 |
| NULL |
+-------------+
200 rows in set (0.00 sec)
-the Final Step, Lets DELETE!
mysql> delete from actor_2 where actor_id in (select first_names from (select if(first_name=#a,actor_id,null) as first_names,#a:=first_name from actor_2 order by first_name) as t1);
Query OK, 72 rows affected (0.01 sec)
-Now lets check our table:
mysql> select count(*) from actor_2 group by first_name;
+----------+
| count(*) |
+----------+
| 1 |
| 1 |
| 1 |
...
| 1 |
+----------+
128 rows in set (0.00 sec)
it works, if you have any question write me back
I have the following table
id name address empid
1 AA aa 0
2 BB bb 0
3 CC cc 0
I need to write a query to set empid starting from 1. How to write it please. Do i have to use a stored procedure to that or can do it with a normal query?
Thank You.
Here is a way to do it that utilizes a pretty obscure assignment operator in MySQL. This solution won't skip numbers in the case of gaps in the primary key sequence like some of the other solutions.
set #count = 0;
update test set empid = #count := #count+1;
Here is the proof:
mysql> create table test (
-> id int unsigned primary key auto_increment,
-> name varchar(32) not null,
-> address varchar(32) not null,
-> empid int unsigned not null default 0
-> ) engine=innodb;
Query OK, 0 rows affected (0.02 sec)
mysql> insert into test (name, address)
-> values ('AA', 'aa'), ('BB', 'bb'), ('CC', 'cc');
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from test;
+----+------+---------+-------+
| id | name | address | empid |
+----+------+---------+-------+
| 1 | AA | aa | 0 |
| 2 | BB | bb | 0 |
| 3 | CC | cc | 0 |
+----+------+---------+-------+
3 rows in set (0.00 sec)
mysql> set #count=0;
Query OK, 0 rows affected (0.00 sec)
mysql> update test set empid = #count := #count+1;
Query OK, 3 rows affected (0.00 sec)
Rows matched: 3 Changed: 3 Warnings: 0
mysql> select * from test;
+----+------+---------+-------+
| id | name | address | empid |
+----+------+---------+-------+
| 1 | AA | aa | 1 |
| 2 | BB | bb | 2 |
| 3 | CC | cc | 3 |
+----+------+---------+-------+
3 rows in set (0.00 sec)
If you are looking to put 1 in empid for the first row, 2 for the second, etc. the easiest way would be to use your id field that is already doing this like so:
UPDATE table
SET empid = id
The only thing you need to worry about is missing numbers in the id column. If that would be an issue and you are missing id numbers, you will have to use a different method. To do that, you would need to do something like this:
DECLARE #counter int
SET #counter = 1
UPDATE table
SET #counter = empid = #counter + 1
As #BiggsTRC suggested you can use id to set empid. If not, you can create stored procedure or some PHP code to do that.
If your ID is not "AutoIncrement" field, you can consider a new column as autoincrement field and assign that value to emp with update query and later delete that new column. (These are some alternates, you need to choose the best one)
UPDATE `test` SET `empid`=`id`
But why would you want to do it? It's pretty much definition of redundancy.