Delete many rows from a table using id in Mysql - mysql

I am a Linux admin with only basic knowledge in Mysql Queries
I want to delete many table entries which are ip address from my table using id,
currently i am using
DELETE from tablename where id=1;
DELETE from tablename where id=2;
but i have to delete 254 entries,so this method is going to take hours,how can i tell mysql to delete rows that i specify,coz i want to skip deleting some entries out of this 254.
Deleting whole table and importing needed entries is not an option.

The best way is to use IN statement :
DELETE from tablename WHERE id IN (1,2,3,...,254);
You can also use BETWEEN if you have consecutive IDs :
DELETE from tablename WHERE id BETWEEN 1 AND 254;
You can of course limit for some IDs using other WHERE clause :
DELETE from tablename WHERE id BETWEEN 1 AND 254 AND id<>10;

how about using IN
DELETE FROM tableName
WHERE ID IN (1,2) -- add as many ID as you want.

if you need to keep only a few rows, consider
DELETE FROM tablename WHERE id NOT IN (5,124,221);
This will keep only some records and discard others.

Something like this might make it a bit easier, you could obviously use a script to generate this, or even excel
DELETE FROM tablename WHERE id IN (
1,
2,
3,
4,
5,
6
);

If you have some 'condition' in your data to figure out the 254 ids, you could use:
delete from tablename
where id in
(select id from tablename where <your-condition>)
or simply:
delete from tablename where <your-condition>
Simply hard coding the 254 values of id column would be very tough in any case.

Others have suggested IN, this is fine. You can also use a range:
DELETE from tablename where id<254 and id>3;
If the ids to delete are contiguous.

Use IN Clause
DELETE from tablename where id IN (1,2);
OR you can merge the use of BETWEEN and NOT IN to decrease the numbers you have to mention.
DELETE from tablename
where (id BETWEEN 1 AND 255)
AND (id NOT IN (254));

DELETE FROM table_name WHERE id BETWEEN 1 AND 256;
Try This.

Hope it helps:
DELETE FROM tablename
WHERE tablename.id = ANY (SELECT id FROM tablename WHERE id = id);

DELETE FROM tablename WHERE id > 0;
OR
DELETE FROM tablename WHERE id <255;
It deletes id from 1 to 254

Related

Remove duplicate records in mysql

I have a table called leads with duplicate records
Leads:
*account_id
*campaign_id
I want to remove all the duplicate account_id where campaign_id equal to "51"
For example, if account_id = 1991 appears two times in the table then remove the one with campaign_id = "51" and keep the other one.
You could use a delete join:
DELETE t1
FROM yourTable t1
INNER JOIN yourTable t2
ON t2.account_id = t1.account_id AND
t2.campaign_id <> 51
WHERE
t1.campaign_id = 51;
There's no problem to delete from a table provided that:
You use the correct syntax.
You have done a backup of the table BEFORE you do any deleting.
However, I would suggest a different method:
Create a new table based on the existing table:
CREATE TABLE mytable_new LIKE mytable;
Add unique constraint (or PRIMARY KEY) on column(s) you don't want to have duplicates:
ALTER TABLE mytable_new ADD UNIQUE(column1,[column2]);
Note: if you want to identify a combination of two (or more) columns as unique, place all the column names in the UNIQUE() separated by comma. Maybe in your case, the constraint would be UNIQUE(account_id, campaign_id).
Insert data from original table to new table:
INSERT IGNORE INTO mytable_new SELECT * FROM mytable;
Note: the IGNORE will insert only non-duplicate values that match with the UNIQUE() constraint. If you have an app that runs a MySQL INSERT query to the table, you have to update the query by adding IGNORE.
Check data consistency and once you're satisfied, rename both tables:
RENAME TABLE mytable TO mytable_old;
RENAME TABLE mytable_new TO mytable;
The best thing about this is that in case that if you see anything wrong with the new table, you still have the original table.
Changing the name of the tables only take less than a second, the probable issue here is that it might take a while to do the INSERT IGNORE if you have a large data.
Demo fiddle
DELETE t1
FROM yourTable t1
INNER JOIN yourTable t2
ON t2.account_id = t1.account_id AND
t2.campaign_id <> 51
WHERE
t1.campaign_id = 51;

MySQL; How to reset id and set new, start at

The id's in one of my MySQL tables actually start from 34567 (34568, 34569, 34570…).
How can I reset all these id's and set 123 as start value: 123, 124, 125, 126…?
Or is there a way to make every id -34444: 34567-34444=123?
P.S. ALTER TABLE table_name AUTO_INCREMENT = 124; isn't what I'm looking for.
If you have deleted all table records and you want to start from 123 for the auto-increment field, then use the following command:
ALTER TABLE table_name AUTO_INCREMENT=123;
As others have said, you probably shouldn't worry about the values of the ids. By definition, they shouldn't have any real meaning anyway.
Having said that, you should be able to just update them as you would any other column:
update table_name
set id = id - 34444
You could then reset the starting AUTO_INCREMENT value so that the next row inserted has a sequential id:
ALTER TABLE table_name AUTO_INCREMENT = <whatever the maximum id is + 1>;
Be aware that doing that will rebuild the table, so it could take a while if it has many rows.
Is this what you are looking for:
select (id-34444) as id from your_table;

Delete duplicated mysql rows with no primary key

Hi i have a mysql table without primary key and i need to delete the duplicated rows. how can i do so?
user_id category_id
1 2
1 3
1 4
1 2
2 2
2 3
2 2
CREATE TABLE temp SELECT DISTINCT * FROM tablename;
ALTER TABLE tablename RENAME junk;
ALTER TABLE temp RENAME tablename;
Since you cannot differentiate 2 identical rows, you cannot delete just one of them. The way you need to think about it is like this:
insert into new_better_table
select user_id, category_id from old_table group by user_id, category_id
It's possible to use a dirty flag with default value 1 and copy only single records with the flag set to 0, then simply remove all dirty records. This way you don't need another table.
Assuming you already created a dirty flag with default value 1:
insert into mytable
select fld1,fld2,fldN,0 as dirty
from mytable
group by duplicate_field
Then you can just delete dirty records:
delete from mytable where dirty = 1
Don't forget to remove the dirty flag. You're done.
The select distinct * solution proposed in another answer will not work in cases where your rows contain null values. A better solution that also prevents future duplicates from appearing in my_table in the first place is as follows:
create table no_dupes like my_table;
alter table no_dupes add unique index(unique_column,or_columns);
insert ignore into no_dupes select * from my_table;
rename table my_table to junk, no_dupes to my_table;

Delete statement in a same table

I need to query a delete statement for the same table based on column conditions from the same table for a correlated subquery.
I can't directly run a delete statement and check a condition for the same table in mysql for a correlated subquery.
I want to know whether using temp table will affect mysql's memory/performance?
Any help will be highly appreciated.
Thanks.
You can make mysql do the temp table for you by wrapping your "where" query as an inline from table.
This original query will give you the dreaded "You can't specify target table for update in FROM clause":
DELETE FROM sametable
WHERE id IN (
SELECT id FROM sametable WHERE stuff=true
)
Rewriting it to use inline temp becomes...
DELETE FROM sametable
WHERE id IN (
SELECT implicitTemp.id from (SELECT id FROM sametable WHERE stuff=true) implicitTemp
)
Your question is really not clear, but I would guess you have a correlated subquery and you're having trouble doing a SELECT from the same table that is locked by the DELETE. For instance to delete all but the most recent revision of a document:
DELETE FROM document_revisions d1 WHERE edit_date <
(SELECT MAX(edit_date) FROM document_revisions d2
WHERE d2.document_id = d1.document_id);
This is a problem for MySQL.
Many examples of these types of problems can be solved using MySQL multi-table delete syntax:
DELETE d1 FROM document_revisions d1 JOIN document_revisions d2
ON d1.document_id = d2.document_id AND d1.edit_date < d2.edit_date;
But these solutions are best designed on a case-by-case basis, so if you edit your question and be more specific about the problem you're trying to solve, perhaps we can help you.
In other cases you may be right, using a temp table is the simplest solution.
can't directly run a delete statement and check a condition for the same table
Sure you can. If you want to delete from table1 while checking the condition that col1 = 'somevalue', you could do this:
DELETE
FROM table1
WHERE col1 = 'somevalue'
EDIT
To delete using a correlated subquery, please see the following example:
create table project (id int);
create table emp_project (id int, project_id int);
insert into project values (1);
insert into project values (2);
insert into emp_project values (100, 1);
insert into emp_project values (200, 1);
/* Delete any project record that doesn't have associated emp_project records */
DELETE
FROM project
WHERE NOT EXISTS
(SELECT *
FROM emp_project e
WHERE e.project_id = project.id);
/* project 2 doesn't have any emp_project records, so it was deleted, now
we have 1 project record remaining */
SELECT * FROM project;
Result:
id
1
Create a temp table with the values you want to delete, then join it to the table while deleting. In this example I have a table "Games" with an ID column. I will delete ids greater than 3. I will gather the targets in a temp table first so I can report on them later.
DECLARE #DeletedRows TABLE (ID int)
insert
#DeletedRows
(ID)
select
ID
from
Games
where
ID > 3
DELETE
Games
from
Games g
join
#DeletedRows x
on x.ID = g.ID
I have used group by aggregate with having clause and same table, where the query was like
DELETE
FROM TableName
WHERE id in
(select implicitTable.id
FROM (
SELECT id
FROM `TableName`
GROUP by id
HAVING count(id)>1
) as implicitTable
)
You mean something like:
DELETE FROM table WHERE someColumn = "someValue";
?
This is definitely possible, read about the DELETE syntax in the reference manual.
You can delete from same table. Delete statement is as follows
DELETE FROM table_name
WHERE some_column=some_value

Is it really no solution to update multiple records in MySQL?

I want to do all these update in one statement.
update table set ts=ts_1 where id=1
update table set ts=ts_2 where id=2
...
update table set ts=ts_n where id=n
Is it?
Use this:
UPDATE `table` SET `ts`=CONCAT('ts_', `id`);
Yes you can but that would require a table (if only virtual/temporary), where you's store the id + ts value pairs, and then run an UPDATE with the FROM syntax.
Assuming tmpList is a table with an id and a ts_value column, filled with the pairs of id value, ts value you wish to apply.
UPDATE table, tmpList
SET table.ts = tmpList.ts_value
WHERE table.id = tmpList.id
-- AND table.id IN (1, 2, 3, .. n)
-- above "AND" is only needed if somehow you wish to limit it, i.e
-- if tmpTbl has more idsthan you wish to update
A possibly table-less (but similar) approach would involve a CASE statement, as in:
UPDATE table
SET ts = CASE id
WHEN 1 THEN 'ts_1'
WHEN 2 THEN 'ts_2'
-- ..
WHEN n THEN 'ts_n'
END
WHERE id in (1, 2, ... n) -- here this is necessary I believe
Well, without knowing what data, I'm not sure whether the answer is yes or no.
It certainly is possible to update multiple rows at once:
update table table1 set field1='value' where field2='bar'
This will update every row in table2 whose field2 value is 'bar'.
update table1 set field1='value' where field2 in (1, 2, 3, 4)
This will update every row in the table whose field2 value is 1, 2, 3 or 4.
update table1 set field1='value' where field2 > 5
This will update every row in the table whose field2 value is greater than 5.
update table1 set field1=concat('value', id)
This will update every row in the table, setting the field1 value to 'value' plus the value of that row's id field.
You could do it with a case statement, but it wouldn't be pretty:
UPDATE table
SET ts = CASE id WHEN 1 THEN ts_1 WHEN 2 THEN ts_2 ... WHEN n THEN ts_n END
I think that you should expand the context of the problem. Why do you want/need all the updates to be done in one statement? What benefit does that give you? Perhaps there's another way to get that benefit.
Presumably you are interacting with sql via some code, so certainly you can simply make sure that the three updates all happen atomically by creating a function that performs all three of the updates.
e.g. pseudocode:
function update_all_three(val){
// all the updates in one function
}
The difference between a single function update and some kind of update that performs multiple updates at once is probably not a very useful distinction.
generate the statements:
select concat('update table set ts = ts_', id, ' where id = ', id, '; ')
from table
or generate the case conditions, then connect it to your update statement:
select concat('when ', id, ' then ts_', id) from table
You can use INSERT ... ON DUPLICATE KEY UPDATE. See this quesion: Multiple Updates in MySQL
ts_1, ts_2, ts_3, etc. are different fields on the same table? There's no way to do that with a single statement.