2013-02-28 6 views
0

Я ударил головой по этой проблеме и просмотрел несколько похожих ситуаций при обмене стеками, и чем больше я читаю, тем больше я сбиваюсь с толку! У меня есть таблица, которая имеет следующее:MySQL удаляет дубликаты в одной таблице

id | zipcode | provider | channel 
--------------------------------- 
1 | 91773 | 342  | 0 
2 | 91773 | 2261  | 177 
3 | 91773 | 5590  | 0 
4 | 91773 | 5590  | 0 
5 | 91773 | 5590  | 135 
6 | 91773 | 5590  | 0 
7 | 91773 | 6010  | 0 
8 | 91773 | 6010  | 0 

Я хочу сохранить только одну запись, и если канал не имеет ничего, кроме 0, то мы держим его. Поэтому он должен вернуть это:

id | zipcode | provider | channel 
--------------------------------- 
1 | 91773 | 342  | 0 
2 | 91773 | 2261  | 177 
5 | 91773 | 5590  | 135 
8 | 91773 | 6010  | 0 

Я пробовал довольно много запросов, но никто не работал. Заранее спасибо.

Edit: Я попробовал некоторые из приведенных примеров, но ни один, кажется, вернуть правильную информацию, лучший примером будет использовать их, и вы можете понять, почему: вставки в значение единорогов

(1, 91773, 342, 0), 
(2, 91773, 2261, 177), 
(3, 91773, 5590, 0), 
(4, 91773, 5590, 0), 
(5, 91773, 5590, 135), 
(6, 91773, 5590, 0), 
(7, 91773, 6010, 0), 
(8, 91773, 6010, 0), 
(9, 91776, 5590, 135), 
(10, 91776, 5590, 0), 
(11, 91776, 6010, 0), 
(12, 91776, 6010, 0); 
+0

Возможный дубликат [как удалить дубликаты в таблице mysql?] (Http://stackoverflow.com/questions/2630440/how-to-delete-duplicates-on-mysql-table) –

+0

Мне кажется, вам нужно сгруппировать по zipcode и провайдеру, а не только по zipcode, я обновил свой ответ, посмотрю, хорошо ли это – fthiella

ответ

0

Я думаю, вы могли бы использовать что-то например:

delete from unicorns 
where id not in (
    SELECT * FROM (
    SELECT MAX(id) 
    FROM unicorns 
    WHERE (provider, zipcode, channel) IN (
     SELECT provider, zipcode, max(channel) mx_channel 
     FROM unicorns 
     GROUP BY provider, zipcode 
    ) 
    GROUP BY provider, zipcode) s) 

См. скрипку here.

+2

Мое единственное колебание в том, что вы 'неверно использовать 'GROUP BY' – Kermit

+0

@AarolamaBluenk, почему неправильно? я возвращаю канал maxumum для каждого провайдера, а затем максимальный идентификатор для каждого провайдера, который имеет максимальное значение ... он выглядит правильно для меня – fthiella

+0

Установите ваш режим SQL на 'ONLY_FULL_GROUP_BY', и вы поймете, почему. MySQL расширяет его функциональность для удобства. Если вы когда-нибудь перейдете на другую платформу, вы будете плакать. Конечно. – Kermit

3

Что-то, как это должно работать ...

DELETE unicorns 
FROM unicorns 
WHERE id NOT IN (SELECT id 
        FROM (SELECT unicorns.provider, 
           Max(id) AS id 
          FROM unicorns 
           LEFT JOIN (SELECT provider, 
                Max(channel) AS channel 
              FROM unicorns 
              GROUP BY provider) p 
             ON p.provider = unicorns.provider 
              AND p.channel = unicorns.channel 
          WHERE p.provider IS NOT NULL 
          GROUP BY unicorns.provider) p2) 

See the demo

+1

Большое спасибо, я даже не был близок к тому, чтобы понять это. Я буду придерживаться графики. :) Еще раз спасибо Ааролама! – Anthony

+0

@aariloama Я протестировал это, и он, похоже, не сработал, он удалил почтовые коды, которые должны содержать по крайней мере один из каждого почтового индекса; он удалил точное количество провайдеров. – Anthony

+0

@Anthony. Попробуйте другие решения. – Kermit

2

Вы можете выполнить это, используя самостоятельное соединение. Если вы просто делаете удаления:

DELETE a 
FROM foo a 
    JOIN foo b on (a.zipcode = b.zipcode AND a.provider = b.provider) 
WHERE 
    a.channel < b.channel; 

Если вы хотите увидеть данные, прежде чем удалить (что останется):

SELECT * 
FROM foo 
WHERE ID NOT IN (
SELECT a.id 
FROM foo a 
    JOIN foo b on (a.zipcode = b.zipcode AND a.provider = b.provider) 
WHERE 
    a.channel < b.channel); 

SQL Fiddle demo

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