我已经看过重复行操作的示例,但我无法弄清楚如何映射它们来解决我的问题。
+----+------------+------+---------+
| 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 |
+----+------------+------+---------+
对于表格中的每个文件:
我需要首先选择/删除状态='待定'的任何行,并且其日期早于状态='完成'的任何行的最新日期。 。例如,这将选择/删除id为1,2,4和13的行。
我需要接下来选择/删除状态='待定'并且它不是状态='待定'的最早的日期。例如,这将选择/删除ID为7,8和10的行。
结果表是:
+----+------------+------+---------+
| 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 |
+----+------------+------+---------+
这将在MySQL中创建并填充测试表:
CREATE TABLE test
(
id
int(11)NOT NULL AUTO_INCREMENT,
date
日期DEFAULT NULL,
file
int(11)DEFAULT NULL,
status
varchar(45)DEFAULT NULL,
主要关键(id
)
)ENGINE = InnoDB AUTO_INCREMENT = 16 DEFAULT CHARSET = latin1;
INSERT INTO test
VALUES(1,' 2011-12-01','待定'),(2,' 2011-12 -02',1,'待定'),(3,' 2011-12-03',1,'完成'),(4, ' 2011-12-04',1,'待定'),(5,' 2011-12-05',1,'完成&# 39;),(6,' 2011-12-06',1,'待定'),(7,' 2011-12-07',1 ,'待定'),(8,' 2011-12-08','待定'),(9,' 2011- 12-09',2,'待定'),(10,' 2011-12-10',2,'等待'),( 11,' 2011-12-11',3,'待定'),(12,' 2011-12-12',4,'完成'),(13,' 2011-12-13','待定'),(14,' 2011-12-14' ,5,'完成'),(15,' 2011-12-15','待定');
感谢ziesemer提供正确的SELECT查询 - 我从中学到了很多东西。不幸的是,MySQL似乎不允许DELETE使用子查询,所以我转换了ziesemer的答案来改为使用JOINS。但我是一个SQL菜鸟,所以请纠正这些是否可以改进:
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;
要删除,请将SELECT行替换为:
DELETE t1 FROM test t1 INNER JOIN test t2
答案 0 :(得分:1)
我已对这些进行了测试,独立工作 - 虽然必须在第一个之后执行第二个以获得您在示例中提供的结果。我很难让它们作为一个Select工作,因为第二个查询取决于第一个完成后表的状态......
Select *
From my_table t1
Where (status = 'Pending'
And date < (
Select Max(date)
From my_table t2
Where t2.file = t1.file
And t2.status = 'Done'));
Select *
From my_table t1
Where (status = 'Pending'
And date > (
Select Min(date)
From my_table t2
Where t2.file = t1.file
And t2.status = 'Pending'));
(我会给予其他任何人一个+1的回答可以在一个查询中做到这一点,同时产生相同的,准确的结果 - 我现在很难过。)
答案 1 :(得分:0)
您的第一个问题将通过以下查询解决,只需要进行子选择:
delete from tables1 where (select * from table1 where status=pending AND file=1 AND date>2011-12-05)
对于另一个需要一点思考。 (让我考虑一下)