Удаление из таблицы одинаковых строк

Basele
Дата: 04.10.2000 06:44:21
Возникла задача
В таблице есть одинаковые строки, например

a b
a c
b a
a c
a b

в таблице нет никаких счетчиков, индексов и т.д. (так сказать совсем чистенькая).
существует ли способ, без использовате временных таблиц удалить дублирующиеся строки
(сделать аналог distinct только чтобы повторяющиеся записи исчезли из таблицы?
Ольга
Дата: 04.10.2000 07:22:36
Или через промежуточную таблицу, в которую сваливаешь все distinct значения, или (если работаешь в 7.0) создаешь дополнительное поле, нумеруешь записи в этом поле, а потом удаляешь строки-дубли с бОльшим порядковым номером, после этого удаляешь вспомогательное поле. Примерный сценарий второго способа (действующие лица: DoubleTable - модифицируемая таблица, Field1, Field2 - поля в таблице, Ind - вспомогательное поле):
alter table DoubleTable add Ind int
go
declare @I int
set @I=0
update DoubleTable
set @I=Ind=@I+1 --Нумерация строк
go
delete DoubleTable
from DoubleTable d1
where Ind<>
(
select min(Ind)
from DoubleTable d2
where d1.Field1=d2.Field1 and
d1.Field2=d2.Field2
group by Field1, Field2
)
go
alter table DoubleTable drop column Ind

Триггера на время этой операции лучше отключить (вдруг у тебя там каскадное удаление стоит :).
Vasily
Дата: 04.10.2000 07:54:29
Только зачем такой update писать для нумерации строк, если можно просто написать

alter table DoubleTable add Ind int IDENTITY

там тогда все автоматом пронумеруется...
Ольга
Дата: 04.10.2000 08:12:37
Действительно, затормозила. Мне почему-то казалось, что IDENTITY нельзя добавлять.
Denis
Дата: 05.10.2000 07:33:05
Извиняйте что вмешиваюсь :)
Предложенные решения к сожалению не всегда будут работать - т.к. добавлять (убивать) колонку у таблицы может только пользователь имеющий соответствующие права!

цитирую Вooks Online:


\nPermissions

ALTER TABLE permissions default to the table owner, members of the sysadmin fixed server role, and to members of the db_owner and db_ddladmin fixed database roles.



Кроме того, добавление колонки и ее использование должны быть в разных батчах - это тоже накладывает определенные ограничения :((

Могу предложить единственное решение поставленой задачи, которое будет работать всегда, к сожалению оно достаточно медленное :(


\nSET ROWCOUNT 1
WHILE 1=1
BEGIN
DELETE t
FROM DoubleTable t
WHERE EXISTS (SELECT 1
FROM DoubleTable tt
WHERE tt.Field1 = t.Field1
AND tt.Field2 = t.Field2
GROUP BY tt.Field1, tt.Field2
HAVING COUNT(*) > 1)
IF @@rowcount = 0 BREAK
END
SET ROWCOUNT 0



по хорошему конечно же следует еще добавить обработку ошибок :))
ZuB
Дата: 06.11.2002 14:01:04
А как быть, если таблица связана с другими ключами?
хм...
Дата: 26.06.2005 16:37:24
declare @I int
set @I=0
update DoubleTable
set @I=Ind=@I+1
а можно пронумеровать строки, исходя из сортировки по какому-либо полю?