Okay so I have a table that has xid. Each xid can have several pids. I am trying to delete everything except the row that has the highest pid for each xid.
I am trying:
DELETE FROM table WHERE `pid` NOT IN
( SELECT MAX(`pid`)
FROM table
GROUP BY `xid`
)
If I use the same query but with SELECT instead of DELETE, I get all of the records that I want to delete. When the DELETE is there, I get the error:
#1093 - You can't specify target table 'mod_personnel' for update in FROM clause
Use a JOIN rather than NOT IN:
DELETE t1.* FROM table t1
LEFT JOIN (SELECT xid, MAX(pid) pid
FROM table
GROUP BY xid) t2
ON t1.pid = t2.pid
WHERE t2.pid IS NULL
DELETE FROM table WHERE `pid` NOT IN
(SELECT maxpid FROM
( SELECT MAX(`pid`) as maxpid
FROM table
GROUP BY `xid`
)as m
)
Related
I have a query in MySQL based on which I am finding duplicate records of some columns.
select max(id), count(*) as cnt
from table group by start_id, end_id, mysqltable
having cnt>1;
This above query gives me the max(id) and the count of number of records that have start_id,end_id,mysqltable column values same.
I want to delete all the records that match the max(id) column of the above query
How can I do that?
I have tried like below
delete from table
where (select max(id), count(*) as cnt
from table group by start_id,end_id,mysqltable
having cnt>1)
But Unable to delete records
You can remove duplicate records using JOIN.
DELETE t1 FROM table t1
INNER JOIN
table t2
WHERE
t1.id > t2.id AND t1.start_id = t2.start_id AND t1.end_id = t2.end_id AND t1.mysqltable = t2.mysqltable;
This query keeps the lowest id and remove the highest.
I think so this command should work:
delete from table
where id in
( select max(id) from table
group by start_id, end_id, mysqltable
having count(*) > 1
);
records in my table are like below:
id |sensor_id|val |audit_date
255245| 1|22.12|2017-02-18 08:26:47
and I want get latest records using this
SELECT `sensor_id`, `val`, `audit_date`
FROM `tests` t1
JOIN (SELECT max(`audit_date`) as audit_date, `sensor_id`
from `tests` group by `sensor_id`) t2
USING (`audit_date`, `sensor_id`)
where `id` > (select max(`id`)-1000 from `tests`)
It takes more than one second; without last "where" - second and half.
"id" is primary key and now indexes.
What I can do to make this query faster?
This query return latest instered record using max() funtion
SELECT t1.sensor_id,val,t1.audit_date
FROM `tests` t1
JOIN (SELECT max(`audit_date`) as audit_date, max(`sensor_id`) as max_sensor_id
FROM `tests` group by `sensor_id`) t2
ON t2.max_sensor_id = t1.sensor_id
AND t2.audit_date =t1.audit_date
You can try if a self-exclusion join would be faster:
SELECT t1.sensor_id, t1.val, t1.audit_date
FROM audit t1
LEFT JOIN audit t2
ON t1.sensor_id = t2.sensor_id
AND t2.audit_date > t1.audit_date
where
t2.id is null
Basically that says return records for which there are no greater audit_dates per sensor_id.
How can i construct a SQL query to delete how i want.
I have two tables.
Table 1.
ID: Some Random Not Significant To This Question Columns : DateTime : UserID
Table 2.
ID: Some Random Not Significant To This Question Columns : DateTime : UserID
The two tables are related by DateTime and UserID
Is there anyway i can create a query so that it deletes from table 2 if no rows in table1 have a matching DateTime & UserID.
Thanks
You can use LEFT JOIN :
DELETE table2
FROM table2 t2 LEFT JOIN table1 t1 ON t1.`DateTime` = t2.`DateTime`
AND t1.`UserID` = t2.`UserID`
WHERE t1.`UserID` IS NULL
DELETE
FROM table2 t2
WHERE NOT EXISTS
(
SELECT NULL
FROM table1 t1
WHERE (t1.userId, t1.dateTime) = (t2.userId, t2.dateTime)
)
First of all: create a backup before you delete lots of records :)
The idea:
DELETE FROM
table1
WHERE
NOT EXISTS (SELECT 1 FROM table2 WHERE table1.referenceColumn = table2.referenceColumn)
You can check which records will be deleted by replacing the DELETE with SELECT *
And now the solution
DELETE FROM
table2
WHERE
NOT EXISTS (
SELECT 1 FROM
table1
WHERE
table2.UserID = table1.UserID
AND table2.DateTime = table1.DateTime
)
We have 2 tables called : "post" and " post_extra"
summery construction of "post" table's are: id,postdate,title,description
And for post_extra they are: eid,news_id,rating,views
"id" filed in the first table is related to "news_id" to the second table.
There are more than 100,000 records on the table, that many of them are duplicated. I want to keep only one record and remove duplicate records on "post" table that have the same title, and then remove the related record on "post_extra"
I ran this query on phpmyadmin but the server was crashed. And I had to restart it.
DELETE e
FROM Post p1, Post p2, Post_extra e
WHERE p1.postdate > p2.postdate
AND p1.title = p2.title
AND e.news_id = p1.id
How can I do this?
Suppose you have table named as 'tables' in which you have the duplicate records.
Firstly you have to do group by column on which you want to delete duplicate.But I am not doing it with group by.I am writing self join instead of writing nested query or creating temporary table.
SELECT * FROM `names` GROUP BY title, id having count(title) > 1;
This query return number of duplicate records with their title and id.
You don't need to create the temporary table in this case.
To Delete duplicate except one record:
In this table it should have auto increment column. The possible solution that I've just come across:
DELETE t1 FROM tables t1, tables t2 WHERE t1.id > t2.id AND t1.title = t2.title
if you want to keep the row with the lowest auto increment id value OR
DELETE t1 FROM tables t1, tables t2 WHERE t1.id < t2.id AND t1.title = n2.title
if you want to keep the row with the highest auto increment id value.
You can cross check your solution,by selecting the duplicate records again by given query:
SELECT * FROM `tables` GROUP BY title, id having count(title) > 1;
If it return 0 result, then you query is successful.
This will keep entries with the lowest id for each title
DELETE p, e
FROM Post p
left join Post_extra e on e.news_id = p.id
where id not in
(
select * from
(
select min(id)
from post
group by title
) x
)
SQLFiddle demo
You can delete duplicate record by creating a temporary table with unique index on the fields that you need to check for the duplicate value
then issue
Insert IGNORE into select * from TableWithDuplicates
You will get a temporary table without duplicates .
then delete the records from the original table (TableWithDuplicates) by JOIN the tables
Should be something like
CREATE TEMPORARY TABLE `tmp_post` (
`id` INT(10) NULL,
`postDate` DATE NULL,
`title` VARCHAR(50) NULL,
`description` VARCHAR(50) NULL, UNIQUE INDEX `postDate_title_description` (`postDate`, `title`, `description`) );
INSERT IGNORE INTO tmp_post
SELECT id,postDate,title,description
FROM post ;
DELETE post.*
FROM post
LEFT JOIN tmp_post tmp ON tmp.id = post.id
WHERE tmp.id IS NULL ;
Sorry I didn't tested this code
This might be something very simple to do. If so, I apologize. I'm still learning MySQL.
Say, I have two tables:
Table1:
`id` int autoincrement primary key
`Name` tinytext
`Phone` tinytext
`Date` etc.
and
Table2:
`id` int autoincrement primary key
`itmID` int
Each row in Table2 specifes the order at which elements should be selected out of Table1. itmID field in Table2 is linked to id field in Table1.
So right at this moment to select elements from Table1 I do this:
SELECT * FROM `Table1`;
But how do you order them according to Table2, something like this?
SELECT * FROM `Table1` ORDER BY <itmID's in Table2> ASC;
If all ids of the Table1 have an entry on Table2 use an INNER JOIN, like this.
SELECT * FROM Table1 t1
INNER JOIN Table2 t2 ON t1.id = t2.itmID
ORDER BY t2.itmID
If not all of them have an entry, then use a LEFT JOIN, like this:
SELECT * FROM Table1 t1
LEFT JOIN Table2 t2 ON t1.id = t2.itmID
ORDER BY t2.itmID
Select from the first table, join it to the second, and order by the second. Something like
SELECT *
FROM table1
LEFT JOIN table 2 on table.id = table2.id
ORDER by table2.itmID
Ryan's answer is almost right
SELECT *
FROM table1
INNER JOIN table2 on table1.id = table2.itmID
ORDER BY table2.id
http://dev.mysql.com/doc/refman/5.5/en/join.html
SELECT * FROM `Table1`
INNER JOIN `Table2` USING (`id`)
ORDER BY `Table2`.`itmID` ASC