2012-03-25 2 views
3

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

table stockData 
(
tickId int not null, 
timestamp datetime not null, 
price decimal(18,5) not null 
) 

Ни tickId, ни временная метка является уникальными, однако сочетание tickId и меток времени должны быть уникальными ,

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

Правильно ли это, или есть какой-то волшебный способ удаления одного, но не двух дублированных данных с запросом?

EDIT Отредактировано для уточнения того, что команда tickId и timestamp combo должна быть уникальной, но это происходит не из-за дублирования данных.

+0

Просто идея, я не знаю, если он работает, или если он будет удалять как: DELETE FROM WHERE stackData tickId IN (SELECT tickId FROM stackData); –

+0

С SQL Server 2005 существует волшебный способ удалить только один из дубликатов. Какую версию SQL-сервера вы используете? После устранения дублированной проблемы вы должны добавить ограничение первичного ключа в таблицу. –

+0

Спасибо Mikael, я использую SQL Server 2005. У меня было уникальное ограничение, однако я объединил данные из нескольких таблиц в одну таблицу, и эти таблицы имели повторяющиеся данные. Я решил, что самый простой способ - просто свалить все в одну таблицу, удалить обманы, а затем добавить ограничение после. – steve8918

ответ

24

Ниже приведен запрос, который удаляет дубликаты и оставляет ровно одну копию каждой уникальной строки. Она будет работать с SQL Server 2005 или выше:

WITH Dups AS 
(
    SELECT tickId, timestamp, price, 
    ROW_NUMBER() OVER(PARTITION BY tickid, timestamp ORDER BY (SELECT 0)) AS rn 
    FROM stockData 
) 
DELETE FROM Dups WHERE rn > 1 
+0

Ничего себе, я никогда раньше не видел ничего подобного, но он выглядит великолепно. Я прочитаю об этом и сделаю некоторые тесты, спасибо! – steve8918

+0

Хороший ответ с первого таймера :) Добро пожаловать в stackoverflow. – Leigh

3

select distinct * into temp_table from source_table (эта таблица будет создана для вас)

удалить из temp_table (что вам не нужно)

insert into sorce_table 
select * from temp_table 
0

Может быть, я не понимая ваш вопрос правильно, но если «tickId "и" timestamp "гарантированно будут уникальными, то как у вас есть дубликаты данных в вашей таблице? Не могли бы вы привести пример или два из того, что вы имеете в виду?

Однако, если у вас есть дубликаты всех трех столбцов внутри таблицы, может работать следующий скрипт. Протестируйте это и сделайте резервную копию базы данных перед реализацией, поскольку я только что собрал ее.

declare @x table 
(
    tickId int not null, 
    timestamp datetime not null, 
    price decimal(18,5) not null 
) 

insert into @x (tickId, timestamp, price) 
select tickId, 
    timestamp, 
    price 
from stockData 
group by tickId, 
     timestamp, 
     price 
having count(*) > 1 

union 

select tickId, 
     timestamp, 
     price 
from stockData 
group by tickId, 
     timestamp, 
     price 
having count(*) = 1 

delete 
from stockData 

insert into stockData (tickId, timestamp, price) 
select tickId, 
     timestamp, 
     price 
from @x 

alter table stockData add constraint 
    pk_StockData primary key clustered (tickid, timestamp) 
+0

сожалею об этом, я имел в виду, что «должно быть» уникальным, однако это не так (из-за дублирования данных). Я уточню вопрос. – steve8918

Смежные вопросы