6

Удалить дублирующиеся строки, сохранив первую строку

17

Как удалить дублирующие строки, если уникальный идентификатор строки отсутствует?

У меня есть таблица, которая выглядит следующим образом:

col1  col2 col3 col4 col5 col6 col7
john  1    1    1    1    1    1 
john  1    1    1    1    1    1
sally 2    2    2    2    2    2
sally 2    2    2    2    2    2

Я хочу, чтобы после удаления дубликатов у меня остались только следующие строки:

john  1    1    1    1    1    1
sally 2    2    2    2    2    2

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

DELETE
FROM table
WHERE col1 IN (
    SELECT id
    FROM table
    GROUP BY id
    HAVING (COUNT(col1) > 1)
)

Не могли бы вы помочь мне решить эту проблему и предоставить запрос, который удаляет дублирующие строки без наличия уникального идентификатора?

5 ответ(ов)

10

Я также люблю использовать CTE и ROW_NUMBER, так как их сочетание позволяет увидеть, какие строки были удалены (или обновлены). Для этого просто замените DELETE FROM CTE... на SELECT * FROM CTE:

WITH CTE AS(
   SELECT [col1], [col2], [col3], [col4], [col5], [col6], [col7],
       RN = ROW_NUMBER() OVER (PARTITION BY col1 ORDER BY col1)
   FROM dbo.Table1
)
DELETE FROM CTE WHERE RN > 1

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

COL1    COL2    COL3    COL4    COL5    COL6    COL7
john    1        1       1       1       1       1
sally   2        2       2       2       2       2

В этом примере дубликаты определяются по одному столбцу col1 благодаря конструкции PARTITION BY col1. Если вы хотите учесть несколько столбцов, просто добавьте их в PARTITION BY:

ROW_NUMBER() OVER (PARTITION BY Col1, Col2, ... ORDER BY OrderColumn)

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

0

Без использования CTE и ROW_NUMBER(), вы сможете удалить дубликаты, применяя GROUP BY вместе с функцией MAX. Вот пример:

DELETE
FROM MyDuplicateTable
WHERE ID NOT IN
(
    SELECT MAX(ID)
    FROM MyDuplicateTable
    GROUP BY DuplicateColumn1, DuplicateColumn2, DuplicateColumn3
)

В этом запросе мы выбираем максимальный ID для каждой группы дубликатов по заданным столбцам DuplicateColumn1, DuplicateColumn2 и DuplicateColumn3. После этого мы удаляем все записи, у которых ID не входит в список максимальных значений, тем самым оставляя только одну запись для каждого набора дубликатов.

0

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

SELECT DISTINCT [col1], [col2], [col3], [col4], [col5], [col6], [col7]
INTO [newTable]
FROM [oldTable]

Затем перейдите в обозреватель объектов и удалите старую таблицу.

После этого переименуйте новую таблицу в имя старой таблицы.

0

Для удаления всех дубликатов, оставляя только первые (с минимальным значением ID), вы можете использовать следующий SQL-запрос. Этот запрос должен работать не только в вашей СУБД, но и в PostgreSQL:

DELETE FROM table
WHERE id NOT IN (
    SELECT MIN(id)
    FROM table
    GROUP BY col1, col2, col3, col4, col5, col6, col7
);

Данный запрос удаляет все записи, у которых ID не является минимальным для каждой группы, определяемой по столбцам col1, col2, col3, col4, col5, col6, col7. Убедитесь, что вы заменили table на имя вашей таблицы и указали правильные названия столбцов, соответствующие вашему случаю.

Примечание: Перед выполнением команды DELETE всегда рекомендуется сделать резервную копию данных или сначала протестировать запрос с помощью SELECT для проверки, какие строки будут удалены.

0

Ваш запрос удаляет дубликаты из таблицы search, оставляя только по одной записи для каждого уникального значения url. Давайте разберем его по частям:

  1. Вложенный запрос:

    select min(id) from search
    group by url
    having count(*) = 1
    

    Здесь мы выбираем минимальный id для тех url, которые встречаются только один раз в таблице.

  2. Объединение с дубликатами:

    union
    
    SELECT min(id) FROM search
    group by url
    having count(*) > 1
    

    В этом разделе мы выбираем минимальный id для url, которые имеют более одной записи.

  3. Основной запрос:

    DELETE from search
    where id not in (...)
    

    Здесь мы находим все записи, чей id не содержится в результатах вложенного запроса, и удаляем их.

Таким образом, итоговый запрос удалит все дубликаты url, оставив по одной записи с наименьшим id для каждого уникального значения url.

Обратите внимание, что если количество записей для url равно 1, то такая запись останется. Если у вас остались вопросы или нужны уточнения, не стесняйтесь спрашивать!

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь