sql удалить все кроме 2 дубликатов - PullRequest
0 голосов
/ 02 февраля 2012

Я хочу иметь возможность ограничить количество повторяющихся записей в таблице базы данных mySQL до 2.

(исключая поле id с автоматическим приращением)

Мой стол настроен как

id    city      item
---------------------
1     Miami     4
2     Detroit   5
3     Miami     4
4     Miami     18
5     Miami     4

Таким образом, в этой таблице будет удалена только строка 5.

Как я могу это сделать?

Ответы [ 5 ]

3 голосов
/ 02 февраля 2012

MySQL имеет некоторые недостатки при чтении и записи в одну и ту же таблицу. Так что я на самом деле не знаю, будет ли это работать, синтаксис хорош во многих реализациях SQL, но я не знаю, является ли он дружественным для MySQL ...

DELETE
  yourTable
WHERE
  1 < (SELECT COUNT(*)
       FROM yourTable as Lookup
       WHERE city = yourTable.city AND item = yourTable.item AND id < yourTable.id)

EDIT

Удивительно запутанный, но стоит попробовать?

DELETE
  yourTable
FROM
  yourTable
INNER JOIN
(
  SELECT
    id
  FROM
  (
    SELECT
      id
    FROM
      yourTable
    WHERE
      1 < (SELECT COUNT(*)
           FROM yourTable as Lookup
           WHERE city = yourTable.city AND item = yourTable.item AND id < yourTable.id)
  )
    AS inner_deletes
)
  AS deletes
    ON deletes.id = yourTable.id
1 голос
/ 02 февраля 2012

Я думаю, что ваша проблема здесь в том, что и ваш код, и / или структура таблицы позволяют вставлять дубликаты, и вы задаете этот вопрос, когда вам действительно нужно исправить свою БД и / или код.

0 голосов
/ 02 февраля 2012

В своем ответе на ответ Иоахима вы спрашиваете о сохранении 3 или 5 строк, это один из способов сделать это.В зависимости от того, как вы используете эту базу данных, вы можете вызвать ее в цикле или превратить в хранимую процедуру.В любом случае вы продолжите запускать весь этот блок кода до тех пор, пока строка не будет затронута = 0:

drop table if exists TempTable;
create table TempTable
select city, item,
       count(*) as record_count, 
       min(id) as ItemToDrop -- this could be changed to max() if you 
                             -- want to delete new stuff instead 
from YourTable
group by city, item
having count(*) > 2; -- This value = number of rows you save

delete from YourTable
where id in (select ItemToDrop from TempTable);
0 голосов
/ 02 февраля 2012

Из-за того, что MySQL общеизвестно труден, когда дело доходит до обновления запрашиваемых таблиц (см., Например, ответы от Dems), лучшее, что я могу выяснить, это, к сожалению, более чем одно утверждение, но с положительной стороны, вполне читабельное;

CREATE TEMPORARY TABLE Dump AS SELECT id FROM table1 WHERE id NOT IN 
  (SELECT MIN(id) FROM table1 GROUP BY city,item UNION
   SELECT MAX(id) FROM table1 GROUP BY city,item);

DELETE FROM table1 where id in (select * from Dump);

DROP TABLE DUMP;

Не уверен, было ли важно, какой дубликат был удален, это сохраняет первый и последний.

0 голосов
/ 02 февраля 2012

я думаю, что лучшее решение - избегать использования более 5 регистров, вы должны выполнить проверку, где, если выберите count (*)> 3, вы не примете новую вставку.

, потому что если вы хотитесделать это на уровне данных, вы должны использовать хранимую процедуру, потому что сначала вам нужно идентифицировать все регистры с более чем 3 регистрами и удалить только последний.Салудос

...