[SQL] Из вопросов на собеседовании: как удалить дубликаты?
а в чем проблема?
Проблемы нет, были несколько решений. Какое круче?
приведи хоть варианты. интересно
так и пишешь, удалить записи, для которых существуют дубликаты. Ну и какой-нибудь элемент из группы дубликатов оставляешь, например, с меньшим ID-шником.
where not id in (select min(id) from tbl group by user, thing)
DELETE FROM
TBL
WHERE
ID IN
(
SELECT A.ID FROM
TBL A,
TBL B
WHERE
A.User=B.User
AND
A.Thing = B.Thing
AND
A.ID <> B.ID
)
AND
ID
NOT IN
(
SELECT MIN (A.ID) FROM
TBL A,
TBL B
WHERE
A.User=B.User
AND
A.Thing = B.Thing
AND
A.ID <> B.ID
)
А я имел в виду MySQL:
ALTER [b]IGNORE[/b] TABLE TBL ADD UNIQUE (User, Thing)
Я лох
в оракле сработает. если в мускуле есть IN, то должно сработать. я не помню.
Но у тебя
not id in,
а у меня
id not in
Думаю, похуй
конечно одно ито же. это у меня выебоны.
Но фикус с alter ignore мне понравился - это точно быстрее любых выборок
DELETE FROM TBL
WHERE EXISTS ( SELECT 1
FROM TBL TBL2
WHERE TBL.User = TBL2.User
AND TBL.Thing = TBL2.Thing
AND TBL.ID > TBL2.ID )
ты только с альтером объясни. разве оно дубликаты удалит? я чот не очень мануал понял.
Удалятся только дубликаты или дубликаты вместе с оригиналами?
Удалит, мы попробовали, точно делает именно то, что надо. Но только в MySQL
AND TBL.ID > TBL2.ID
дадад, я как раз хотел оправдаться
да, нашел на русском. у тебя круче решение. я в альтере не силен. тем более мускульном.
а игнор как раз только там и есть
у меня фэйл. удаление из подзапросов - это расширение над ANSI.
А не судьба с темп-таблицей? Мне дочитать лень:)
а для тебя у меня тоже плохие новости. ignore - это тоже расширение
with cte as (
select
row_number over (partition by [user], thing order by Id) rn
from tbl
)
delete cte
where rn > 1
Ребята имели в видуребята или ты сам это придумал?
DELETE FROM
TBL
WHERE
ID IN
(
SELECT A.ID FROM
TBL A,
TBL B
WHERE
A.User=B.User
AND
A.Thing = B.Thing
AND
A.ID <> B.ID
)
AND
ID
NOT IN
(
SELECT MIN (A.ID) FROM
TBL A,
TBL B
WHERE
A.User=B.User
AND
A.Thing = B.Thing
AND
A.ID <> B.ID
)
у ребят тоже подзапрос. тоже пусть расслабятся. ответа верного никто пока не привел.
ну наверно можно создать таблицу, в нее инсертом залить данные и потом обратно.вместо обратной переливки можно старую таблицу drop-нуть, а временную переименовать в старую
какой ASNI имеется ввиду? в какой-нибудь 2003 даже row_number входит, имхо
можно. а теперь это все одним запросом...
я ваще хз. это нужно просто давно иметь дело с базами. когда модных наворотов не было.
вместо обратной переливки можно старую таблицу drop-нуть, а временную переименовать в старуювы всю таблицу собираетесь переливать, а дубликат может оказаться один на миллиард?
select min id,a,b from tbl group by a,b
в какой-нибудь 2003 даже row_number входитда в ISO SQL:2003 входит
http://en.wikipedia.org/wiki/Window_function_%28SQL%29#Limit...
PS MS SQL Server
Действительно интересны однострочные решения, которые займут времени не сильно больше переиндексации по одному из полей
а дубликат может оказаться один на миллиардименно
а может оказаться и полмиллиарда на миллиард
"это вынос мозга"
from tbl
delete from (select * from tbl) что вроде должно соответствовать delete from tbl.
так вот, все что я смог сделать - это
CREATE TABLE tbl1 AS select id, user, thing from tbl where id in (select min(id) from tbl group by user, thing)
кстати тот запрос что я привел первым тоже не работает. поскольку в условии не указано что нельзя создавать другую таблицу, то походу - это оно.
так
ALTER IGNORE TABLE tbl ADD UNIQUE (User, Thing)
у меня тоже не работает, к слову.
CREATE TABLE tbl1 AS select id, user, thing from tbl where id in (select min(id) from tbl group by user, thing)
CREATE TABLE tbl1 AS SELECT min(id) as id, user, thing FROM tbl GROUP BY user, thing
ну да. копипастил из кучи селектов, навставлял при этом ошибок. все исправил кроме этого.
DELETE from tbl WHERE not EXISTS (
SELECT q.ID FROM (
select min(b.id) id from tbl b group by b.user, b.thing
) q where tbl.id = q.id
);
Как, оказывается, всё depends от реализации и версии
Ну, лови, раз обещал:
rowid?
Хотя это будет не анси, они у всех по разному декларируются, зато не привязаны ко всяким суррогатным ID
delete from table_1 a where rowid not in (select min(rowid user, thing from table_1 b where a.user = b.user and a.thing = b.thing group by user, thing)
может по
rowid?
Хотя это будет не анси, они у всех по разному декларируются, зато не привязаны ко всяким суррогатным ID
Вроде rowid неуникальны в случае кластерной таблицы.
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUES...
Оставить комментарий
uncle17
ЕстьTBL:
ID primary key
User int
Thing int
На User,Thing не поставлен UNIQUE
Как одним ANSI-запросом вычистить дубликаты, которые появились? У кого какие идеи? Чисто сравнить