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)
Related
I have two tables which have member data (linked with 'member_id' column)
I need to search for all records where the email column ends in '.pl'. I then need to delete all records from the two tables for this (based on the 'member_id').
Is it possible to complete this in one SQL statement?
SELECT member_id
FROM exp_members
WHERE email LIKE '%.pl'
delete t1, t2
from exp_members t1
join table2 t2 on t1.member_id = t2.member_id
where t1.email LIKE '%.pl'
Delete from Members where Member_id = (SELECT member_id
FROM exp_members
WHERE email LIKE '%.pl')
I am trying to delete duplicates from a table based on the customer phone number. The inner select query below correctly selects all duplicate records which I need to delete, however the outter delete query generates the following error:
You can't specify target table 'customers' for update in FROM clause
Query:
DELETE FROM customers WHERE id IN (SELECT id from customers GROUP BY phone HAVING COUNT(phone) > 1)
In an update and delete statement, you often cannot reference the table being modified. An easy solution is to use a join:
DELETE c
FROM customers c JOIN
(SELECT phone, COUNT(*) as cnt
FROM customers c
GROUP BY phone
) p
ON c.phone = p.phone AND cnt > 1;
Note that this deletes all duplicates from the table. Normally, you want to keep one of them:
DELETE c
FROM customers c LEFT JOIN
(SELECT phone, MIN(id) as minid
FROM customers c
GROUP BY phone
) p
ON c.id = p.minid
WHERE p.phone IS NULL;
I have multiple tables as table_1 has id , p_code, profile_status, name and table_2 has id, p_code, availablity and table_3 has id, p_code, status...
How to get all records form all tables depend on p_code.
table_2 and table_3 has few records. if p_code not in table_2 and table_3 then echo 'no' in results.
currently i am using my query as below
select t.id, t.p_code,t.name,t.num_rooms, t.profile_status, t.distance FROM (
( SELECT id , p_code, profile_status, name,num_rooms, 3956 * 2 * ASIN(SQRT( POWER(SIN(($origLatAirport - latitude)*pi()/180/2),2)
+COS($origLatAirport*pi()/180 )*COS(latitude*pi()/180)
*POWER(SIN(($origLonAirport-longitude)*pi()/180/2),2)))
as distance FROM property WHERE profile_status=1 having distance < ".$dist." ) ) as t
How to add table_2 and table_3 and fetch results.
Pleasr reply soon. I am stuck here.
In your query you are doing CROSS JOIN and what you desire, is probably INNER JOIN.
In MySQL the CROSS JOIN behaves like JOIN and INNER JOIN of without using any condition.
The CROSS JOIN returns all rows form user multiplied by all rows from user_inbox - for every user you get inboxes of all users.
You should specify condition for your JOIN statement.
$sql_alt = mysql_query(
"select i.*,u.images, u.firstname, u.lastname
from user_inbox i INNER JOIN user u ON i.to_id = u.user_id
where i.to_id = '$user_id'");
Also it is good habit have the same names for primary and foreign keys, so I think you should have user_id or user_id_to instead of to_id in your user_inbox table. This is of course not absolutely necessary.
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?
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)