I am trying to use the following code to remove duplicate entries from a column called herit. The name of my table is people
DELETE FROM people
WHERE herit NOT IN (SELECT *
FROM (SELECT MIN(n.herit)
FROM people n
GROUP BY n.herit) x)
Although this code is executed and it states "5 rows affected", it doesn't remove duplicates from my table in mysql.
What could possibly be wrong? I searched all over the internet, couldn't find anything satisfactory
Try this one..
DELETE FROM people WHERE id NOT IN
(SELECT id FROM (SELECT id FROM people GROUP BY herit HAVING count(herit) > 1
OR count(herit) = 1) newTable)
This is actual and resultant table
Related
first I will like to state that am still a newbie on writing SQL Queries. I thoroughly searched for an answer on this Error and I got a good number of answers, but none seems to be helpful or I will say I don't really know how to apply the solutions to mine.
Here is my challenge, I have an application table, that stores applicants records with some unique columns e.g (dl_number,parent_id,person_id). The parent_id keeps tracks of individual applicant history records with the his/her first record and each applicant is meant to have a unique dl_number, but for some reasons, some applicants dl_number(s) are not unique, hence a need to identify the records with changing dl_number(s).
Below is the SQL Query, that am getting the [sql error (1241) operand should contain 1 column(s)] error on.
SELECT id,application_id,dl_number,surname,firstname,othername,birth_date,status_id,expiry_date,person_id,COUNT(DISTINCT(dl_number,parent_id,birth_date)) AS NumOccurrences
FROM tbl_dl_application
WHERE status_id > 1
GROUP BY dl_number,parent_id,birth_date
HAVING NumOccurrences > 1
Please any help on how to solve this, or a better way to solve this.
Sample table and expected result
DISTICT is not really a function to be used that way.
You can do SELECT DISTICT column1, column2 FROM table to get unique rows only, or similarly SELECT column, count(DISTINCT anothercolumn) FROM table GROUP BY column to get unique rows within a group.
Problem as I understand it: You look for duplicates in your table. Duplicates are defined as having identical values of these 3 columns: dl_number, parent_id and birth_date.
I'm also assuming that id is a primary key in your table. If not, replace the t2.id <> t.id condition with one that uniquely identify your row.
If you only wanted to know what are the duplicated groups, this should work:
SELECT dl_number, parent_id, birth_date, count(*) as NumOccurences -- You can only add aggregation functions here, not another column unless you group by it.
FROM tbl_dl_application t
WHERE status_id > 1 -- I don't know what this is but it should do no harm.
GROUP BY dl_number, parent_id, birth_date
HAVING count(*)>1
If, however, you want to know details of each duplicated row, this query will give you that:
SELECT *
FROM tbl_dl_application t
WHERE
status_id > 1 -- I don't know what this is but it should do no harm.
AND EXISTS (
SELECT 1
FROM tbl_dl_application t2
WHERE
t2.dl_number = t.dl_number
AND t2.parent_id = t.parent_id
AND t2.birth_date = t.birth_date
AND t2.id <> t.id
)
ORDER BY dl_number, parent_id, birth_date, id; -- So you have your duplicates nicely next to each other.
Please explain further if I misunderstood your objective, or ask if the solution is not clear enough.
**You have to use only one column while use to DISTINCT function. You used this three field dl_number,parent_id,birth_date. Just use 1 filed from these 3. Then query will run.**
For example.
SELECT id,application_id,dl_number,surname,firstname,othername,birth_date,status_id,expiry_date,person_id,COUNT(DISTINCT(parent_id)) AS NumOccurrences
FROM tbl_dl_application
WHERE status_id > 1
GROUP BY dl_number,parent_id,birth_date
HAVING NumOccurrences > 1
Question - let's say I have 2 tables.
Table 1 - name is permission_list, columns are ID (unique ID), col_ID, user_ID
Table 2 - name is list_entries, Columns are ID (unique ID), title, description, status
I want to select all the rows from table 2 that have status of 'public' as well as all the rows from table 2 that the ID from table 2 shows up in table 1 (under the column col_ID) AND if the user_ID in table 1 matches a certain value. So, anything public, or anything that this specific user has listed under the permissions table. This query would also remove duplicates - in case the user gets a public entry listed in their permissions_list, it wouldn't show up twice.
Hope that makes sense!
Here you go:
SELECT DISTINCT table2.* from table2
LEFT JOIN table1 USING (id)
WHERE status='public'
OR user_ID='someuser';
You need to get some education on JOIN for your first thing, and the second thing is called DISTINCT.
Start here... https://www.google.com/
You have not specified your join condition so we can't give you code samples really. Also the way you worded your question, I'm not entirely sure you don't want a UNION. Read up on those concepts and come back here when you can improve the question.
SELECT table_2.status, table_2.ID, table_1.col_ID
FROM table_1 JOIN table_2
WHERE table_2.status = 'public'
AND table_2.ID = table_1.col_ID
AND table_1.user_ID = 'certain value'
;
Try this
I'm trying to insert rows into a table (usersteps) from the table steps for all users only if the step id does not exist.
INSERT INTO userssteps
(status,user_id,step_id)
SELECT
'0' ,
(SELECT DISTINCT id from users),
(SELECT DISTINCT id from steps)
I get the following error on the above MYSQL
#1242 - Subquery returns more than 1 row
Reason:
A new user signs up they should get all steps, if I create a new step i'd want to create it in usersteps for current users to see.
If there is a more clever way to do this i'd love to know but i'm stumped. I am also using cakePHP so if there is a special cakePHP way to help me in this i'd prefer that.
Table Structure
steps:
id
name
users:
id
username
password
userssteps:
id
user_id
step_id
status
It looks like you are trying to produce a cartesian product. http://en.wikipedia.org/wiki/Cartesian_product.
If there is no relations between the users and steps table then they cannot be joined, only multiplied.
INSERT INTO userssteps
(status,user_id,step_id)
select 0,
users.id,
steps.id
from users
inner join steps
The subquerys (SELECT DISTINCT id from users) and (SELECT DISTINCT id from steps) will return ALL the id's. In a insert clause you will need only one value (you can't have more than 1 value).
you can try to inner join the two tables by the ID
Try this way:
INSERT INTO userssteps
(status,user_id,step_id)
select 0 as status,
users.id,steps.id
from users
inner join steps
on (users.id=steps.user_id);
That way should works ;)
PS: Now the join is right.
Saludos.
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...
I copied some records from one table to another
with this query :
insert into pages_finished (keyword,pages,resultlist,done,current)
select keyword,pages,resultlist,done,current
from pages_done o
where (select count(*) as totalPages from pages_done x where x.keyword = o.keyword)-1 = pages
Now I want to delete the same records from the source table,
I was thinking it would be simple as:
delete from pages_done o
where (select count(*) as totalPages from pages_done x where x.keyword = o.keyword)-1 = pages
but that doesn't work.
Could anyone tell me what is the right way to do that?
After #bgdrl answer, I'm thinking about running only the select,
get the id's of all records that should be copied,
and then delete;
but I think there must be an easier solution, anyone?
Even though marked #bgdrl answer as the right answer,
it is only because of that a fact.
To anyone interested with what I ended up doing :
I did the same select I started with (but selected only the id column, since selecting all the columns would have killed my poor computer),
exported it to an INSERT STATMENTS (using mysqlworkbench),
opened the text file in notepad,
replaced all the INSERT INTO... with DELETE FROM WHERE ID=,
and run that query in mysql.
I feel so stupid using this way, but had no other choice apparently.
From mysql site: "You cannot modify a table and select from the same table in a subquery. This applies to statements such as DELETE, INSERT, REPLACE, UPDATE". http://dev.mysql.com/doc/refman/5.1/en/subqueries.html
PLEASE BACKUP THE TABLE BEFORE FOLLOWING THE STEPS.
Follow the following STEPS
STEP 1
CREATE TABLE pages_done_ids
SELECT o.id FROM pages_done AS o
WHERE
(
SELECT count(*) AS totalPages
FROM pages_done AS x
WHERE x.keyword = o.keyword
)-1 = o.pages
STEP 2
DELETE FROM pages_done AS o
WHERE o.id IN (SELECT id FROM pages_done_ids)
STEP 3
DROP TABLE pages_done_ids;
OK, you may accomplish it with one transaction using TEMPORARY TABLES.
Happy Querying!