This question already has answers here:
Delete Duplicate SQL Records
(2 answers)
Closed 8 years ago.
My table name is emails.
My table structures looks like:
I want to remove all of the duplicated emails. I tried this query:
DELETE FROM emails WHERE email NOT IN (SELECT MIN(email)
FROM emails GROUP BY email)
But with no result. Can someone help me with this?
The query that you are looking for would use id, not email:
DELETE FROM emails
WHERE id NOT IN (SELECT MIN(id) FROM emails GROUP BY email) ;
EDIT:
You are using MySQL. You can get around this with the subquery hack:
DELETE FROM emails
WHERE id NOT IN (select minid from (SELECT MIN(id) as minid FROM emails GROUP BY email) e) ;
Or, you can use a join:
delete e
from emails e left outer join
(select min(id) as minid
from emails
group by email
) em
on e.id = e.minid
where em.id is null;
Try this instead
--CREATE a Temporary table
create table IDsToRemove (ID Int)
INSERT INTO IDStoRemove
SELECT MIN(id) _
FROM emails GROUP BY email
DELETE FROM emails WHERE id NOT IN (SELECT id from IDStoRemove)
I don't know the exact mySQL syntax, but should give you the idea
Maybe you (or someone) wants to delete records that are unique, I'll just leave this stolen answer here[0].
DELETE Emails
FROM Emails
LEFT OUTER JOIN (
SELECT MIN(id) as id, email, pwd
FROM Emails
GROUP BY email, pwd
) as KeepRows ON
Emails.id = KeepRows.id
WHERE
KeepRows.id IS NULL
0.How can I remove duplicate rows?
Related
Here is a question from LEETCODE.I don't know why my output is wrong. First I write the SELECT in the parenthesis to find out the repeated email address. Then I use the DELETE to filter out the repeated email address so anyone know what is wrong with my code? questionmycode
output
it is very simple. try this
-- Solution 1
with cte as
(
select id, email, Rank() OVER (partition by email order by id) ranks
from person where email in(
select email from person
group by email having count(email) >1
)
)
DELETE FROM person where id in
(
SELECT id FROM CTE where ranks!=1
)
-- Solution 2
DELETE p from person p
inner join (
select MIN(id) id, email from person
where email in(
select email from person group by email having count(email)>1
) group by email
) A On P.Id>A.id and p.email = a.email;
I have to write a SQL query to delete all duplicate email entries in a table named Person, keeping only unique emails based on its smallest Id. Id is the primary key column for this table.
This is the query I wrote:
delete from Person
where Email not in (select distinct Email from Person)
But I get this error:
You can't specify target table 'Person' for update in FROM clause
You Can Try This .
DELETE p1 FROM Person p1
INNER JOIN Person p2
WHERE
t1.id < t2.id AND
t1.Email = t2.Email ;
You are using MySQL, which does not allow that syntax. Use join instead:
delete p
from Person p left join
(select email, min(id) as min_id
from person p
group by email
) pp
on pp.id = min_id
where pp.min_id is null; --no match
Of course, your logic is wrong anyway. But even with the correct logic, not in/not exists is not going to work in MySQL. You need to use a join of some sort.
you can use IN keyword after grouping the Person table to Email
delete from Person where id not in (
select min(id) as ID from Person group by Email)
i have 10 similar tables in my database. all the tables have the same field email in them. i want to find out email addresses that occur in more than 3 tables. the field email is not a primary key.
Thanks in advance.
You could use a count function over a union all query:
SELECT email, COUNT(*) AS num_tables
FROM (SELECT DISTINCT email FROM table1
UNION ALL
SELECT DISTINCT email FROM table2
UNION ALL
-- All the other tables
) t
GROUP BY email
HAVING COUNT(*) > 1
When I run the below query I get
error #1093 - You can't specify target table 'x2' for update in FROM clause
update contacts
set duplicates = 1
where email in ( select email from contacts
group by email
having count(*) > 1)
Any help would be appreciated.
You can do a JOIN to find other rows with the same email and a different primary key.
For example, assuming your primary key is called id:
UPDATE contacts AS c1
JOIN contacts AS c2 ON (c1.email = c2.email AND c1.id <> c2.id)
SET c1.duplicates = 1;
I think you can trick it by nesting the subquery.
update contacts set duplicates = 1 where email in
(select email
from
(select email from contacts group by email having count(*) > 1) as a)
I use to do
SELECT email, COUNT(email) AS occurences
FROM wineries
GROUP BY email
HAVING (COUNT(email) > 1);
to find duplicates based on their email.
But now I'd need their ID to be able to define which one to remove exactly.
The second constraint is: I want only the LAST INSERTED duplicates.
So if there's 2 entries with test#test.com as an email and their IDs are respectively 40 and 12782 it would delete only the 12782 entry and keep the 40 one.
Any ideas on how I could do this? I've been mashing SQL for about a hour and can't seem to find exactly how to do this.
Thanks and have a nice day!
Well, you sort of answer your question. You seem to want max(id):
SELECT email, COUNT(email) AS occurences, max(id)
FROM wineries
GROUP BY email
HAVING (COUNT(email) > 1);
You can delete the others using the statement. Delete with join has a tricky syntax where you have to list the table name first and then specify the from clause with the join:
delete wineries
from wineries join
(select email, max(id) as maxid
from wineries
group by email
having count(*) > 1
) we
on we.email = wineries.email and
wineries.id < we.maxid;
Or writing this as an exists clause:
delete from wineries
where exists (select 1
from (select email, max(id) as maxid
from wineries
group by email
) we
where we.email = wineries.email and wineries.id < we.maxid
)
select email, max(id), COUNT(email) AS occurences
FROM wineries
GROUP BY email
HAVING (COUNT(email) > 1);
delete from wineries
where id not in
(
select * from
(
select min(id)
from wineries
group by email
) x
)
You need a subquery to trick MySQL to delete from a table it is selecting from at the same time.
DELETE duplicates.*
FROM wineries
JOIN wineries AS duplicates USING (email)
WHERE duplicates.id < wineries.id;
play with it on sqlfiddle.com
This is the simplest option:
DELETE FROM wineries
WHERE id NOT IN
(
SELECT MIN(id) id
FROM wineries
GROUP BY email
);
This will only keep the first inserted record for each email address, all other records will be deleted. Credit for this answer should go to #juergen d since this is just a revised version of his answer.