2011-12-24 2 views
2

Я видел примеры для дублирования манипуляций строк, но я не могу понять, как их сопоставить для решения моей проблемы.выбор и удаление строк внутри групп с использованием mysql

+----+------------+------+---------+ 
| 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 | 
+----+------------+------+---------+ 

Для каждого файла в таблице:

  1. мне нужно сначала выбрать/удалить любую строку, где статус = «В ожидании», и дата его старше младшей даты для любой строки, где статус = «Готово». Например, это будет выбирать/удалять строки с идентификаторами 1, 2, 4 и 13.

  2. Мне нужно следующее выбрать/удалить любую строку, где status = 'Pending', и это не самая старая дата, где status = «В ожидании». Для примера, это выбрать бы/удалить строки с идентификатором 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) По умолчанию значение NULL, status VARCHAR (45) По умолчанию значение NULL, ПЕРВИЧНЫЙ КЛЮЧ (id) ) ДВИГАТЕЛЬ = InnoDB AUTO_INCREMENT = 16 = 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 , «Ожидание»), (12, «2011-12-12», 4, «Готово»), (13, 2011-12-13, 5, «Ожидание»), (14, 2011-12- 14 ', 5,' Done '), (15,' 2011-12-15 ', 5,' Pending ');

Благодаря 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; 

Чтобы удалить, заменить ВЫБЕРИТЕ линию:

DELETE t1 FROM test t1 INNER JOIN test t2 

ответ

1

Я тестировал их, работая независимо - хотя второй должен быть выполнен после первого, чтобы получить результаты, которые вы предоставили в своем примере. У меня возникают трудности с тем, чтобы они работали как один Select, так как второй запрос зависит от состояния таблицы после завершения 1-го ...

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 к кому-либо еще, кто Ответит могут сделать это в одном запросе, производя те же, точные результаты -. Я в тупике, на данный момент)

+0

Это Безразлично» t нужно выбрать один или удалить, если это невозможно. Но у меня возникают проблемы с превращением этих выборок в удаления. Можете ли вы показать мне, как это сделать? Я использую 5.5.16. Спасибо. – osoviejo

+0

Просто замените первый 'Select * From' на' Delete From' (только для внешнего запроса, а не для внутреннего запроса). – ziesemer

+0

Вот что я пробовал: MySQL> Удалить -> Из тестового t1 -> Где (статус = 'В ожидании' -> И дата <( -> Выберите Max (дата) -> Из тестового t2 -> Где t2.file = t1.file -> И t2.status = 'Done')); ERROR 1064 (42000): У вас есть ошибка в синтаксисе SQL; проверьте руководство, соответствующее версии вашего сервера MySQL, для правильного синтаксиса для использования рядом с 't1 Где (status =' Pending ' И дата <( ) Выберите Max (dat' at line 2 – osoviejo

0

Ваша первая задача будет решена ниже запроса , просто вам нужно сделать подзаголовок:

delete from tables1 where (select * from table1 where status=pending AND file=1 AND date>2011-12-05) 

для другого нужно немного подумать. (позвольте мне задуматься)