Remove rows that are already in another table - mysql

I have 2 mySQL tables. They are both lists of personal info (names, phone numbers, emails etc).
Although the field names are similar, they are not identical.
I need to remove rows from the 1st table containing phone numbers that are found in the second table.
Is this possible and can someone point me in the right direction?
Thanks in advance.

delete t1
from first_table t1
join second_table t2 on t1.phone = t2.phone

Try this:
DELETE FROM `table1` WHERE `phonenumber` IN (SELECT `phonenumber` FROM `table2`)

First, write a query that identifies the set of rows you want to remove. For example:
SELECT o.*
FROM table_one o
JOIN table_two t
ON o.phone_number = t.phone_number
Verify that this is the set of rows you want to remove. (This is also convenient if you want to store a backup copy of the rows you are going to delete. If there are multiple rows from table_two that have the same phone number, you can add a GROUP BY clause with the primary key of table_one, or a DISTINCT keyword, etc.)
Convert the SELECT statement into a DELETE statement by replacing the SELECT keyword and the select list with DELETE o.* (if it's rows from table_one you want to remove.)

Related

Alternative to NOT IN?

I need to check two tables and find inconsistencies, ie where the value of table T1 is not present in the italy_cities table. I'll explain:
T1: Includes personal data (with place of birth)
italy_city: Includes all the municipalities of Italy.
Table T1 has about 9000 tuples.
T2 has 7,903 tuples.
Using "NOT IN" the query takes approximately 16 seconds to execute.
Here is the query:
SELECT
`T1`.*
FROM
T1
WHERE
(
`T1`.place NOT IN ( SELECT municipality FROM italy_cities )
)
MY QUESTION
what is the best and fast option to check for inconsistencies? to check all the "incorrect" municipalities that do not exist in the official database?
Thanks in advance
I generally recommend NOT EXISTS for this purpose:
SELECT T1.*
FROM T1
WHERE NOT EXISTS (SELECT 1
FROM italy_cities ic
WHERE t1.place = ic.municipality
);
Why? There are two reasons:
NOT IN does not do what you expect if the subquery returns any NULL values. If even one value is NULL all rows end up being filtered out.
This version of the query can take advantage of an index on italy_cities(municipality) which seems like a reasonable index on the table.
Not exists can perform better but there is also another way which is left join as follows:
SELECT T1.*
FROM T1
LEFT JOIN italy_cities I ON I.municipality = T1.PLACE
WHERE I.municipality IS NULL;

select from database table rows that are not in another table

I have a table of 'entries' in a MYSQL database. I have another table that records activity on those entries, with the id of the entry as a foreign key. I want to select from my first table entries that do not appear in the second table.
How can I use SQL to make this happen? Do I have to iterate through both tables and compare every entry with every other entry? Is there an easier way to do this?
ex. I have a table with an entry data column and a user name column. I have another table with an entry id column and a user id column. I want to select from my first table all of the entries which do not appear in the second table with a given user id.
Thanks ahead of time. I have been struggling with this experiment for a while. I imagine I have to join the two tables somehow?
Several ways to achieve this, NOT IN, NOT EXISTS, LEFT JOIN / NULL check. Here's one with NOT EXISTS:
SELECT *
FROM FirstTable T
WHERE NOT EXISTS (
SELECT *
FROM SecondTable T2
WHERE T.Id = T2.Id
)
From what I understand, you want to select all rows where the foreign key doesn't match anything in the other table. This should do the trick:
SELECT *
FROM Data A
RIGHT JOIN Entry B
ON A.ID = B.ID
WHERE A.ID IS NULL
Here's a handy chart that illustrates how to use joins for stuff like this.
You can also use NOT IN, and the mechanics for this one are actually a bit easier to understand.
SELECT *
FROM Data A
WHERE A.ID NOT IN (SELECT ID FROM Entry)

Getting a string from a referenced table

I am relativly new to the SQL language. I can do a basic select, but for performance increase, I'd love to know if it is possible to merge the two queries I am doing at the moment into one.
Scenario: There are two tables. Table one has a few columns, one of them is a VARCHAR(45) named 'user', and another one is a INT which is called 'gid'. In the second table, there is a primary key column called 'gid' (INT) and a column called 'permissions' which is a TEXT column and it contains values seperated by ';'.
I have a user name, and want the text in the permissions column. The current way I do it is by fetching the gid of the first table, then doing a second query with the gid to get the permissions.
I've heard there are other ways to do this, and I have searched on Google, but I'm not sure what I should do.
EDIT:
Like this:
select t2.permissions
from table1 t1, table2 t2
where t1.user = '<SPECIFIED NAME>'
and t1.gid = t2.gid;
or you could use INNER JOIN syntax:
select t2.permissions
from table1 t1
inner join table2 t2 on t1.gid = t2.gid
where t1.user = '<SPECIFIED VALUE>'
To do this you use a JOIN. A join connects two tables in a select statement.
Like this
select *
from usertable u
join permissiontable p on u.gid = p.gid
This will give you all the columns from both tables with the id column joined. You can treat the joined table just like any table (eg select a sub-set of columns in the select list, add a where clause, etc).
You can read more about joins in any intro sql book or doing a google search.

MYSQL join query advice (removing orphaned rows)

I have two tables as follows..
campaigns(campaignID, title)
campaignMailList(campaignID, Sent)
(The 2 tables are bigger.. but for this purpose I only need these columns)
I want to do generate a query that will DELETE all rows in campaignMailList where it cannot find a join in the campaigns table on the campaignID.
Can anyone suggest how I do this?
Translating word by word your own question into SQL:
delete from campaingMailList where
campaingId not in (select campaingid from campaigns)
You could try the NOT IN clause.
Like
DELETE FROM `campaignMailList` as cml
WHERE cml.campaignid NOT IN ( SELECT campaignID FROM campaigns )
Not sure if it is the fatest way to do this
Try this query -
DELETE cml FROM campaignMailList cml
LEFT JOIN campaigns c
ON c.campaignID = cml.campaignID
WHERE c.campaignID IS NULL

Deleting duplicate rows with sql

I am trying to delete duplicate rows from my mysql table. I've tried multiple queries but I am keep on getting this error: #1093 - You can't specify target table 'usa_city' for update in FROM clause
The table looks like this:
usa_city
--------
id(pk)
id_state
city_name
And the queries I have tired were:
DELETE FROM usa_city
WHERE id NOT IN
(
SELECT MIN(id)
FROM usa_city
GROUP BY city_name, id_state
)
And:
DELETE
FROM usa_city
WHERE usa_city.id IN
-- List 1 - all rows that have duplicates
(SELECT F.id
FROM usa_city AS F
WHERE Exists (SELECT city_name, id_state, Count(id)
FROM usa_city
WHERE usa_city.city_name = F.city_name
AND usa_city.id_state = F.id_state
GROUP BY usa_city.city_name, usa_city.id_state
HAVING Count(usa_city.id) > 1))
AND usa_city.id NOT IN
-- List 2 - one row from each set of duplicate
(SELECT Min(id)
FROM usa_city AS F
WHERE Exists (SELECT city_name, id_state, Count(id)
FROM usa_city
WHERE usa_city.city_name = F.city_name
AND usa_city.id_state = F.id_state
GROUP BY usa_city.city_name, usa_city.id_state
HAVING Count(usa_city.id) > 1)
GROUP BY city_name, id_state);
Thanks in advance.
Try to select the duplicates first, the delete them
DELETE FROM usa_city WHERE city_id IN
(
SELECT city_id FROM usa_city
GROUP BY city_name, id_state
HAVING count(city_id) > 1
)
Hope it helps!!!
MODIFIED: Based on the comment, if you want to keep one record, you can make a join and keep the lowest value
DELETE c1 FROM usa_city c1, usa_city c2 WHERE c1.id < c2.id AND
(c1.city_name= c2.city_name AND c1.id_state = c2.id_state)
Be sure to make a backup before executing the query above...
from mysql documentation:
"Currently, you cannot delete from a table and select from the same
table in a subquery."
but here is a workaround for update, should work for delete too.
also, you could select rows, and then in php for example delete them in loop
You may found here an answer to your problem: How to delete duplicate records in mysql database?
You should improve your database by using keyfields to prevent duplicate rows, so you dont need to clear in future.
Edit : This solution is also found if you follow the link posted by BloodyWorld, so if it works please go and upvote DMin's post here
Found this browsing the internet (#1 google result for mysql delete duplicate rows), have you tried it?
delete from table1
USING table1, table1 as vtable
WHERE (NOT table1.ID=vtable.ID)
AND (table1.field_name=vtable.field_name)
Judging from your examples, when you say "duplicate", you mean "having the same combination of id_state and city_name", correct? If so after you have done removing the duplictes, I strongly suggest creating a UNIQUE constraint on {id_state, city_name}.
To actually remove the duplicates, it is not enough to just identify the set of duplicates, you must also decide which of the identified duplicates to keep. Assuming you want to keep the ones with the smallest id, the following piece of SQL will do the job:
CREATE TEMPORARY TABLE usa_city_to_delete AS
SELECT id FROM usa_city T1
WHERE EXISTS (
SELECT * FROM usa_city T2
WHERE
T1.id_state = T2.id_state
AND T1.city_name = T2.city_name
AND T1.id > T2.id
);
DELETE FROM usa_city
WHERE id IN (SELECT id FROM usa_city_to_delete);
DROP TEMPORARY TABLE usa_city_to_delete;
Unfortunately, MySQL does not allow the correlated subqueries in DELETE, otherwise we could have done that in a single statement, without the temporary table.
--- EDIT ---
You can't have a correlated subquery but you can have JOIN, as illustrated by Carlos Quijano answer. Also, the temporary table can be created implicitly, as suggested by Kokers.
So it is possible to do it in a single statement, contrary to what I wrote above...