MySQL удалить все результаты подзапроса

Итак, если вам нужна предыстория, посмотрите мой предыдущий вопрос

Выяснить, какая из моих записей не является дубликатом, довольно просто:

SELECT *
FROM eventlog
GROUP BY event_date, user
HAVING COUNT(*) = 1
ORDER BY event_date, user

Это возвращает все мои не дубликаты. Поэтому я решил переместить их в другую таблицу с именем «no_duplicates», а затем удалить их из исходной таблицы. Затем я мог видеть дубликаты в исходной таблице, исправлять их и добавлять обратно no_dupes. Но пока:

INSERT INTO no_duplicates
SELECT *
FROM eventlog
GROUP BY event_date, user
HAVING COUNT(*) = 1
ORDER BY event_date, user

Работает как шарм, следующее выдает ошибку:

DELETE
FROM eventlog
GROUP BY event_date, user
HAVING COUNT(*) = 1
ORDER BY event_date, user

Я предполагаю, что, хотя запрос возвращает уникальные записи, уже находящиеся в таблице, удаление с помощью агрегатной функции не является кошерным. Что понятно, за исключением того, что я не знаю, что еще я могу сделать, чтобы обеспечить удаление только тех записей, которые я переместил. Я искал и не нашел синтаксиса «После того, как INSERT уничтожит записи в исходной таблице», и я предполагаю, что он все равно потерпит неудачу по той же причине, по которой не удалось удалить.

Итак, может ли кто-нибудь помочь мне найти недостающую часть?


person Anthony    schedule 08.09.2009    source источник


Ответы (5)


Во-первых, вам не нужен ORDER BY для INSERT и DELETE. Это просто полезно, если они вам нужны для презентации, что не относится к этим операциям.

Если ваша таблица EVENTLOG имеет первичный ключ (например, ID), вы можете сформировать свой оператор DELETE следующим образом:

DELETE 
FROM eventlog
WHERE id IN (
  SELECT *
  FROM eventlog
  GROUP BY event_date, user
  HAVING COUNT(*) = 1
)
person Kosi2801    schedule 08.09.2009

Я бы не стал удалять с агрегатной функцией. Я думаю, вы хотели бы удалить все вставленные данные?

Почему бы не попробовать что-то вроде этого:

DELETE 
FROM eventlog
WHERE (user, event_date) IN (SELECT user, event_data FROM no_duplicates)
person bernhardrusch    schedule 08.09.2009
comment
Итак, чтобы было ясно. помещение предложения WHERE в круглые скобки означает, что и пользователь, и дата события должны быть в определенной строке таблицы no_duplicates? Потому что, очевидно, пользователи и event_dates повторяются независимо друг от друга. Хорошо, я ненавижу показаться поспешным или некомпетентным, поэтому, пожалуйста, простите меня. Я очень беспокоюсь, потому что восстановление этого займет еще больше времени и еще больше разозлит людей на меня. Я ненавижу сроки. - person Anthony; 08.09.2009
comment
Да, но чтобы быть на 100 % уверенным, всегда делайте резервную копию перед тем, как пробовать операторы. - person bernhardrusch; 08.09.2009
comment
Таким образом, это означает, что оператор удаляет все строки, в которых user AND event_date такие же, как в строке из no_duplicates. Я думаю, это то, что вы хотите? В противном случае вам пришлось бы указать лучший ключ (id?) - person bernhardrusch; 08.09.2009
comment
еще один совет - если вы хотите проверить, работает ли оператор удаления, используйте предложение where с выбором *. Затем вы увидите все строки, которые будут удалены. [Возможно, есть некоторые крайние случаи, когда это утверждение не сработает, но я не могу придумать ни одного) - person bernhardrusch; 08.09.2009
comment
На самом деле, вместо того, чтобы удалять их, я просто сделал SELECT, чтобы отображались только дубликаты (в основном, SELECT * FROM eventlog WHERE id NOT IN (SELECT id FROM duplicates). Оказывается, иметь ключи было удобно во многих очевидных случаях. Постучите по голове. - person Anthony; 08.09.2009
comment
Этот синтаксис с несколькими полями действительно спас меня. спасибо. - person Noah Goodrich; 01.04.2010
comment
Да, синтаксис с несколькими полями удобен. - person bernhardrusch; 11.04.2011

Какая база данных? Если MySQL, то

В настоящее время вы не можете удалить из таблицы и выбрать из той же таблицы в подзапросе.

По крайней мере для версии 5.0. ( http://dev.mysql.com/doc/refman/5.0/en/delete.html )

person Pavlo Svirin    schedule 08.09.2009

Вы должны взглянуть на синтаксис DELETE, там нет ни GROUP BY, ни ИМУЩЕСТВА, ни ЗАКАЗЫ.

person soulmerge    schedule 08.09.2009
comment
Извините, я хватал все так эффективно, как только мог. Я знаю, что ЗАКАЗЫ не нужны для удаления вещей. И я быстро узнал, что GROUP BY и HAVINGs отсутствуют, отсюда и вопрос. - person Anthony; 08.09.2009
comment
ORDER не разрешены в DELETE (кроме того, что это бессмысленно) - person soulmerge; 08.09.2009
comment
ORDER абсолютно разрешено в DELETE в MySQL. И так уже очень и очень давно. < i>Если оператор DELETE включает предложение ORDER BY, строки удаляются в порядке, указанном в предложении. Это полезно в первую очередь в сочетании с LIMIT. ... ORDER BY также может быть полезен в некоторых случаях для удаления строк в порядке, необходимом для предотвращения нарушений ссылочной целостности. ORDER BY можно использовать с DELETE, начиная с MySQL 4.0.0. - person dkarp; 24.04.2015

Вы можете попробовать добавить столбец с автоматическим приращением первичного ключа, переместить свои уникальные данные в новую таблицу и выполнить удаление журнала событий.

person SiViG    schedule 08.09.2009