TGStat
TGStat
Type to search
Advanced channel search
  • flag English
    Site language
    flag Russian flag English flag Uzbek
  • Sign In
  • Catalog
    Channels and groups catalog Regional compilations Thematic compilations Платные каналы Search for channels
    Add a channel/group
  • Ratings
    Rating of channels Rating of groups Posts rating
    Ratings of brands and people
  • Analytics
  • Search by posts
  • Telegram monitoring
  • Promotion
    Advertising through Yandex Business Advertising in channels through TGStat Agency Advertising on TGStat.ru website
Айти-Пингвин | Дата инженер

28 Apr 2025, 09:59

Open in Telegram Share Report

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

Это очень популярный вопрос на собеседовании 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
Catalog
Channels and groups catalog Channels compilations Search for channels Add a channel/group
Ratings
Rating of Telegram channels Rating of Telegram groups Posts rating Ratings of brands and people
API
API statistics Search API of posts API Callback
Our channels
@TGStat @TGStat_Chat @telepulse @TGStatAPI
Read
Академия TGStat Telegram Research 2019 Telegram Research 2021 Telegram Research 2023
Contacts
Справочный центр Support Email Jobs
Miscellaneous
Terms and conditions Privacy policy Public offer
Our bots
@TGStat_Bot @SearcheeBot @TGAlertsBot @tg_analytics_bot @TGStatChatBot