I've seen examples for duplicate row manipulation, but I can't figure out how to map them to solve my problem.
+----+------------+------+---------+
| id | date | file | status |
+----+------------+------+---------+
| 1 | 2011-12-01 | 1 | Pending |
| 2 | 2011-12-02 | 1 | Pending |
| 3 | 2011-12-03 | 1 | Done |
| 4 | 2011-12-04 | 1 | Pending |
| 5 | 2011-12-05 | 1 | Done |
| 6 | 2011-12-06 | 1 | Pending |
| 7 | 2011-12-07 | 1 | Pending |
| 8 | 2011-12-08 | 1 | Pending |
| 9 | 2011-12-09 | 2 | Pending |
| 10 | 2011-12-10 | 2 | Pending |
| 11 | 2011-12-11 | 3 | Pending |
| 12 | 2011-12-12 | 4 | Done |
| 13 | 2011-12-13 | 5 | Pending |
| 14 | 2011-12-14 | 5 | Done |
| 15 | 2011-12-15 | 5 | Pending |
+----+------------+------+---------+
For each file in the table:
I need to first select/delete any row where status='Pending', and its date is older than the youngest date for any row where status='Done'. For the example, this would select/delete rows with id 1, 2, 4, and 13.
I need to next select/delete any row where status='Pending' and it's not the oldest date where status='Pending'. For the example, this would select/delete rows with id 7, 8, and 10.
The resulting table is:
+----+------------+------+---------+
| id | date | file | status |
+----+------------+------+---------+
| 3 | 2011-12-03 | 1 | Done |
| 5 | 2011-12-05 | 1 | Done |
| 6 | 2011-12-06 | 1 | Pending |
| 9 | 2011-12-09 | 2 | Pending |
| 11 | 2011-12-11 | 3 | Pending |
| 12 | 2011-12-12 | 4 | Done |
| 14 | 2011-12-14 | 5 | Done |
| 15 | 2011-12-15 | 5 | Pending |
+----+------------+------+---------+
This will create and populate the test table in MySQL:
CREATE TABLE test
(
id
int(11) NOT NULL AUTO_INCREMENT,
date
date DEFAULT NULL,
file
int(11) DEFAULT NULL,
status
varchar(45) DEFAULT NULL,
PRIMARY KEY (id
)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=latin1;
INSERT INTO test
VALUES (1,'2011-12-01',1,'Pending '),(2,'2011-12-02',1,'Pending '),(3,'2011-12-03',1,'Done'),(4,'2011-12-04',1,'Pending '),(5,'2011-12-05',1,'Done'),(6,'2011-12-06',1,'Pending '),(7,'2011-12-07',1,'Pending '),(8,'2011-12-08',1,'Pending '),(9,'2011-12-09',2,'Pending '),(10,'2011-12-10',2,'Pending '),(11,'2011-12-11',3,'Pending '),(12,'2011-12-12',4,'Done'),(13,'2011-12-13',5,'Pending '),(14,'2011-12-14',5,'Done'),(15,'2011-12-15',5,'Pending ');
Thanks to ziesemer for the correct SELECT queries--I learned a lot from them. Unfortunately, it appears that MySQL doesn't allow DELETE with a subquery, so I converted ziesemer's answer to use JOINS instead. But I'm a SQL noob, so please correct if these could be improved:
SELECT DISTINCT t1.* FROM test t1 INNER JOIN test t2
WHERE t1.file = t2.file
AND t1.status = 'Pending'
AND t2.status = 'Done'
AND t1.date < t2.date;
SELECT DISTINCT t1.* FROM test t1 INNER JOIN test t2
WHERE t1.file = t2.file
AND t1.status = 'Pending'
AND t2.status = 'Pending'
AND t1.date > t2.date;
To delete, replace the SELECT line with:
DELETE t1 FROM test t1 INNER JOIN test t2