TGStat
TGStat
Введите текст для поиска
Расширенный поиск каналов
  • flag Russian
    Язык сайта
    flag Russian flag English flag Uzbek
  • Вход на сайт
  • Каталог
    Каталог каналов и чатов Региональные подборки Тематические подборки Платные каналы Поиск каналов
    Добавить канал/чат
  • Рейтинги
    Рейтинг каналов Рейтинг чатов Рейтинг публикаций
    Рейтинги брендов и персон
  • Аналитика
  • Поиск по публикациям
  • Мониторинг Telegram
  • Продвижение
    Реклама через Яндекс Бизнес Реклама в каналах через TGStat Agency Реклама на сайте TGStat.ru
Айти-Пингвин | Дата инженер

28 Apr 2025, 09:59

Открыть в Telegram Поделиться Пожаловаться

Как удалить дубли из таблицы?

Это очень популярный вопрос на собеседовании lvl jun.
И это сложнее вопроса, где нужно просто найти дубли 😄

📌Допустим у нас есть таблица:

create table table_1
(id numeric,
name varchar(32));

insert into table_1 values(1, 'Jon');
insert into table_1 values(1, 'Jon');
insert into table_1 values(1, 'Jon');

insert into table_1 values(2, 'Sam');
insert into table_1 values(2, 'Sam');
commit;

select * from table_1;

id name

1 "Jon"
1 "Jon"
1 "Jon"
2 "Sam"
2 "Sam"

И нам нужно из 5 строк оставить только 2 уникальные.

Очень популярный НЕВЕРНЫЙ ответ:
Нумеруем оконкой все строки, оставляем все строки с номером 1:

WITH cte AS (
SELECT
id,
name,
ROW_NUMBER() OVER (PARTITION BY id,name ORDER BY id,name ) AS row_num
FROM
table_1
)
----
id name row_num

1 "Jon" 1
1 "Jon" 2
1 "Jon" 3
2 "Sam" 1
2 "Sam" 2

----
DELETE FROM table_1
WHERE id IN (
SELECT id FROM cte WHERE row_num > 1
);
Такой код удалит все строки!

Объясняю. В cte нумируем строки оконкой ROW_NUMBER().
Далее в delete мы хотим удалить все, где row_num > 1. Но под это условие попадают id=1 и id=2. Следовательно, delete удаляет все id с такими значениями. Таблица теперь пустая.

Нам нужно как-то разделить полностью уникальные строки.
В этом нам поможет скрытое системное поле, которое уникально идентифицирует строки и есть в каждой таблице. Такие поля есть во всех СУБД (возможны исключения 🤷‍♂️). В Oracle это поле называется rowid, в Postgresql - ctid.

Чуть переделаем предыдущий код:

WITH cte AS (
SELECT
id,
name,
ctid,
ROW_NUMBER() OVER (PARTITION BY id,name ORDER BY id,name ) AS row_num
FROM
table_1
)

----
id name ctid row_num

1 "Jon" "(0,41)" 1
1 "Jon" "(0,42)" 2
1 "Jon" "(0,43)" 3
2 "Sam" "(0,44)" 1
2 "Sam" "(0,45)" 2

----
DELETE FROM table_1
WHERE ctid IN (
SELECT ctid FROM cte WHERE row_num > 1
);

Теперь удалится только 3 строки, вместо 5.
Останется две уникальные.

id name

1 "Jon"
2 "Sam"

Или же можно удалить таким образом:

DELETE FROM table_1
WHERE ctid NOT IN (
SELECT MIN(ctid)
FROM table_1
GROUP BY id,name
);


Если дальше разгонять, то на самом деле можно придумать еще много способов для удаления дублей.
Например, таблицу с дублями переименовать в table_1_old. Создать новую таблицу table_1 и залить в нее данные из table_1_old без дублей (в select добавить distinct). После дропаем table_1_old.

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

* У меня есть оракловый pl sql cкрипт, который удаляет дубли в таблице через курсор и коллекции. Такой вариант на больших данных будет быстрее работать и не будет блочить всю таблицу. Кому нужен скрипт пишите, пришлю.

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


Как вам инфа? Пишите свои варианты удаления дублей или какие-то еще тонкости и уточнения по данному вопросу? Жду реакций ⬇️😊

it пингвин | data engineer 🐧

#sql #база #jun #Вопросы_с_собесов

1.1k 1 21 21 27
Каталог
Каталог каналов и чатов Подборки каналов Поиск каналов Добавить канал/чат
Рейтинги
Рейтинг каналов Telegram Рейтинг чатов Telegram Рейтинг публикаций Рейтинги брендов и персон
API
API статистики API поиска публикаций API Callback
Наши каналы
@TGStat @TGStat_Chat @telepulse @TGStatAPI
Почитать
Академия TGStat Исследование Telegram 2019 Исследование Telegram 2021 Исследование Telegram 2023
Контакты
Справочный центр Поддержка Почта Вакансии
Всякая всячина
Пользовательское соглашение Политика конфиденциальности Публичная оферта
Наши боты
@TGStat_Bot @SearcheeBot @TGAlertsBot @tg_analytics_bot @TGStatChatBot