2017-02-02 4 views
2

Таблица с пятью соответствующими полями;Как удалить лишние строки в таблице MySQL?

ID (Autoincrement,unique, etc) 
ID_customer - ties in each row to another table with customers, not unique, not NULL 
value1 - can be 0 and NULL (NULL is not 0) 
value2 - can be 0 and NULL (NULL is not 0) 
type - can be 1 or 0 

Я хочу, чтобы пройти через стол и найти каждый случай, когда клиент имеет более чем одну строку, и если существует несколько строк с одинаковым значением по типу, удалять любые такие строки, которые имеют только 0s в их стоимости колонны. Например;

1 1 40 8 1 
2 1 0 0 1 <-- 
3 1 30 5 0 
4 1 45 8 0 

В этом случае команде необходимо удалить указанную строку, но оставить ее неповрежденными. Не слишком сложно. Нечто подобное, вероятно, работать (повторить для типа = 0):

DELETE FROM table 
WHERE value1 = 0 AND value2 = 0 AND type = 1 
    AND ID_customer IN 
     (SELECT ID_customer 
     FROM table 
     WHERE type = 1 GROUP BY ID_customer HAVING count(*) > 1) 

Проблема в том, подобные случаи могли бы существовать:

5 2 0 0 1 
6 2 0 0 1 <-- 
7 2 0 0 0 
8 2 0 0 0 <-- 

В этом случае я хотел бы, чтобы удалить два из строк, но не все строки. Есть ли способ удалить дубликаты строк, но только если столбцы значений равны 0s? Будет ли эта работа (опять же, повторяется для type = 0), или я что-то упускаю?

DELETE 
FROM TABLE 
WHERE value1 = 0 AND value2 = 0 AND TYPE = 1 
    AND ID NOT IN 
    (SELECT ID 
    FROM TABLE 
    WHERE value1 = 0 AND value2 = 0 AND TYPE = 1 
    GROUP BY ID_customer) 

редактировать: Я посмотрел на другие вопросы удаления дубликатов, но я не могу найти тот, который определяет подзапросы в порядке мой стол требует (в том, где я хочу, чтобы сохранить некоторые из дублей).

+0

Может ли быть более одного дубликата для каждого пользователя и ввести его? – Shadow

+0

Да, если столбцы значений отличны от нуля. – Pontus

+0

@JanZeiseweis Опять же, тема, которую вы отметили как дубликаты, отвечает только на вторую часть, а не на первую часть. Запрос на удаление в вопросе даст синтаксическую ошибку (не может выбрать из той же таблицы, которая изменяется) – Shadow

ответ

1

Так что для первой задачи:

Ваш запрос для первой задачи вызывает ошибку (You can't specify target table 'table1' for update in FROM clause

Однако, если вы используете производную таблицу (вложенности подзапроса) он работает просто отлично:

DELETE 
FROM table1 
WHERE value1 = 0 
    AND value2 = 0 
    AND TYPE = 1 
    AND ID_customer IN 
     (SELECT ID_customer 
     FROM 
      (SELECT ID_customer 
       FROM table1 
       WHERE TYPE = 1 
       GROUP BY ID_customer 
       HAVING count(*) > 0) AS derived) 

Для второй задачи подход очень похож, но и с использованием поля ID:

DELETE 
FROM table1 
WHERE ID IN 
     (SELECT dups.ID 
     FROM 
      (SELECT t1.ID 
       FROM table1 t1 
       JOIN table1 t2 ON t1.ID_Customer = t2.ID_Customer 
       AND t1.value1 = t2.value1 
       AND t1.value2 = t2.value2 
       AND t1.type = t2.type 
       AND t1.ID > t2.ID 
       WHERE t1.value1 = 0 
        AND t2.value2 =0) AS dups); 

Надеюсь, это поможет.

+0

Есть ли причина, по которой вы делаете это обруч всего двух столов, кроме того, чтобы гарантировать, что вы выбираете «первую» строку? Разве подобное решение, аналогичное тому, которое вы предоставили первой проблеме, не работает одинаково хорошо, чтобы решить проблему, которую вы не можете удалить из той же таблицы, на которую вы ссылаетесь? – Pontus

+0

С «целым двойным столом». Наверное, вы имеете в виду «self-JOIN». На самом деле это альтернативный способ поиска дубликатов, вы, вероятно, можете сделать то же самое, используя 'group by'. Мне просто было удобно, что я так делаю. –

+0

Gotcha, спасибо. – Pontus

Смежные вопросы