SQL query to delete multiple rows - mysql

How we can delete multiple rows having columns from a db?
Suppose db has following data (id, list_name, user) and list_name has values as:
Owner-aaa
coowner-aaa
owner-aaa
subowner-aaa
How we can delete the rows having "Owner-aaa" and "owner-aaa" which are duplicates?
Can we add something in this query here:
delete from <table_name> where list_name = 'owner-aaa'
But it deletes only lower case list, I want something general which checks duplicates in small and caps and delete both of them?
Thanks in advance
Amy

DELETE FROM mytable WHERE LOWER(listname) IN
(SELECT LOWER(listname) FROM mytable
GROUP BY LOWER(listname)
HAVING COUNT(*) > 1)

delete from tableName where LOWER(list_name) = 'owner-aaa'

Meaby you can use LOWER/UPPER sql functions.
But are you sure your model is correct? It seem realy weird to have a name list like that. That should be another table NAMES with ID and NAME field. It's a 1-N relation.

I'm not entirely sure from your question whether you want to delete all rows where duplicates occur, or leave one, and remove only the true duplicates. So here's a shot at each:
To remove only the true duplicates:
DELETE FROM MyTable WHERE id IN
(
SELECT T1.id
FROM MyTable T1
INNER JOIN MyTable T2
ON UPPER(T1.list_name) = UPPER(T2.list_name)
AND T2.id <> T1.id
AND (T1.id <> (SELECT MAX(id) FROM MyTable WHERE UPPER(list_name) = UPPER(T1.list_name))
) DUPS
This presumes that the id field is unique to each record
To remove all records where there are duplicates, remove the two "AND" clauses in the subquery.

DELETE a
FROM list a
INNER JOIN list b ON LOWER(a.list_name)=LOWER(b.list_name)
WHERE a.id <> b.id

Related

Using group by in SET clause

I'm trying to update a column of a table so that is equal to the count of something in another table. Like this:
UPDATE TABLE
SET TOTAL = (SELECT COUNT(f1)
FROM TABLE2
GROUP BY f2);
But I keep getting sub query returns more than 1 row, and I can't think of how to fix it.
UPDATE (copied from the comment)
f2 is the relation between TABLE and TABLE2 – Thomasd d
Based on your comment
f2 is the relation between TABLE and TABLE2
you probably want something like this
UPDATE TABLE T1, (SELECT f2, COUNT(F1) cnt FROM TABLE2 GROUP BY f2) T2
SET T1.TOTAL = T2.cnt
WHERE T1.f2=T2.f2
adapt T1.f2 if necessary
UPDATE t1
SET total = ( SELECT COUNT(f1)
FROM t2
WHERE t1.f2 = t2.f2 );
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=91de17deff657f66fa54b42fe20ed3c5
Add WHERE total IS NULL if you do not need to recalculate values for rows which have a value already.
Your subquery is returning multiple values and your SET statement is only expecting one. This might fix your code if that is what you are looking for.
UPDATE TABLE
SET TOTAL = (SELECT COUNT(f1)
FROM TABLE2)

Insert missing records from one table to another using mysql

I don't know why I am confused with this query.
I have two table: Table A with 900 records and Table B with 800 records. Both table need to contain the same data but there is some mismatch.
I need to write a mysql query to insert missing 100 records from Table A to Table B.
In the end, both Table A and Table B should be identical.
I do not want to truncate all the entries first and then do a insert from another table. So please any help is appreciated.
Thank you.
It is also possible to use LEFT OUTER JOIN for that. This will avoid subquery overhead (when system might execute subquery one time for each record of outer query) like in John Woo's answer, and will avoid doing unnecessary work overwriting already existing 800 records like in user2340435's one:
INSERT INTO b
SELECT a.* FROM a
LEFT OUTER JOIN b ON b.id = a.id
WHERE b.id IS NULL;
This will first select all rows from A and B tables including all columns from both tables, but for rows which exist in A and don't exist in B all columns for B table will be NULL.
Then it filter only such latter rows (WHERE b.id IS NULL),
and at last it inserts all these rows into B table.
I think you can use IN for this. (this is a simpliplification of your query)
INSERT INTO table2 (id, name)
SELECT id, name
FROM table1
WHERE (id,name) NOT IN
(SELECT id, name
FROM table2);
SQLFiddle Demo
AS you can see on the demonstration, table2 has only 1 records but after executing the query, 2 records were inserted on table2.
If it's mysql and the tables are identical, then this should work:
REPLACE INTO table1 SELECT * FROM table2;
This will insert the missing records into Table1
INSERT INTO Table2
(Col1, Col2....)
(
SELECT Col1, Col2,... FROM Table1
EXCEPT
SELECT Col1, Col2,... FROM Table2
)
You can then run an update query to match the records that differ.
UPDATE Table2
SET
Col1= T1.Col1,
Col2= T1.Col2,
FROM
Table T1
INNER JOIN
Table2 T2
ON
T1.Col1 = T2.Col1
Code also works when a group by and having clauses are used. Tested SQL 2012 (11.0.5058) Tab1 is source with new records, Tab 2 is the destination to be updated. Tab 2 also has an Identity column. (Yes folks, real world is not as neat and clean as the lab assignments)
INSERT INTO Tab2
SELECT a.T1,a.T2,a.T3,a.T4,a.Val1,a.Val2,a.Val3,a.Val4,-9,-9,-9,-9,MIN(hits) MinHit,MAX(hits) MaxHit,SUM(count) SumCnt, count(distinct(week)) WkCnt
FROM Tab1 a
LEFT OUTER JOIN Tab2 b ON b.t1 = a.t1 and b.t2 = a.t2 and b.t3 = a.t3 and b.t4 = a.t4 and b.val1 = a.val1 and b.val2 = a.val2 and b.val3 = a.val3 and b.val4 = a.val4
WHERE b.t1 IS NULL or b.Val1 is NULL
group by a.T1,a.T2,a.T3,a.T4,a.Val1,a.Val2,a.Val3,a.Val4 having MAX(returns)<4 and COUNT(distinct(week))>2 ;

deleting duplicate records on mysql?

I have this mysql query that finds duplicates and the number of occurances for each topic:
SELECT name,
COUNT(name) AS NumOccurrences
FROM topics
GROUP BY name
HAVING ( COUNT(name) > 1 )
but what I want to do is delete all the duplicates that are found. I only want one unique name for each topic, and no duplicates!! thanks
DELETE t2
FROM topics t1
JOIN topics t2
ON t2.name = t1.name
AND t2.id < t1.id
I would copy all the unique entries to a new table:
CREATE TABLE new_table as
SELECT * FROM old_table WHERE 1 GROUP BY unique_column_name;
Check the data, then delete your old table when you're sure everything's good and rename the new table to the old one.
Then make the name column unique so you won't have to do this again.
Cheers

Update a field thanks to a subquery based on another field

I use a MySQL DB, and I would like to update a field in a table based on another. Something like:
UPDATE table1
SET field1 = table2.id
WHERE field2 IN (
SELECT table2.name
FROM table2
);
I know that this query wouldn't work, but here is the idea. Is that even possible to do?
You can use a correlated sub query as below. This assumes there will be exactly one matching value returned. It will raise an error if more than one matching value is returned or set the field to null if zero are returned. If that last behaviour isn't desirable you will need a where clause.
UPDATE table1
SET field1 = (SELECT DISTINCT table2.ValueColumn
FROM table2
WHERE table2.JoinColumn = table1.JoinColumn)
Edit
To review records with 0 or more than 1 matches you could use
SELECT table1.JoinColumn, COUNT(DISTINCT table2.ValueColumn)
FROM table1
LEFT JOIN table2
ON table2.JoinColumn = table1.JoinColumn
GROUP BY table1.JoinColumn
HAVING COUNT(DISTINCT table2.ValueColumn) <> 1

Select a record that has a duplicate

I'd like to select all records from a table (names) where lastname is not unique. Preferably I would like to delete all records that are duplicates.
How would this be done? Assume that I don't want to rerun one query multiple times until it quits.
To find which lastnames have duplicates:
SELECT lastname, COUNT(lastname) AS rowcount
FROM table
GROUP BY lastname
HAVING rowcount > 1
To delete one of the duplicates of all the last names. Run until it doesn't do anything. Not very graceful.
DELETE FROM table
WHERE id IN (SELECT id
FROM (SELECT * FROM table) AS t
GROUP BY lastname
HAVING COUNT(lastname) > 1)
The fastest and easiest way to delete duplicate records is my issuing a very simple command.
ALTER IGNORE TABLE [TABLENAME] ADD UNIQUE INDEX UNIQUE_INDEX ([FIELDNAME])
This will lock the table, if this is an issue, try:
delete t1 from table1 t1, table2 t2
where table1.duplicate_field= table2.duplicate_field (add more if need ie. and table.duplicate_field2=table2.duplicate_field2)
and table1.unique_field > table2.unique_field
and breakup into ranges to run faster
dup How can I remove duplicate rows?
DELETE names
FROM names
LEFT OUTER JOIN (
SELECT MIN(RowId) as RowId, lastname
FROM names
GROUP BY lastname
) as KeepRows ON
names.lastname = KeepRows.lastname
WHERE
KeepRows.RowId IS NULL
assumption: you have an RowId column
SELECT COUNT(*) as mycountvar FROM names GROUP BY lastname WHERE mycountvar > 1;
and then
DELETE FROM names WHERE lastname = '$mylastnamevar' LIMIT $mycountvar-1
but: why don't you just flag the fielt "lastname" als unique, so it isn't possible that duplicates can come in?