2017-01-18 4 views
2

У меня есть ситуация в моей таблице SQL Server, где у меня есть многочисленные дубликаты записей, как следующее:Удаления дубликатов из таблицы SQL Server

SID Username        InQueue 
------------------------------------------------------------------  
162 peeeer2 492 2017-01-18 12:20:21.820 0 354 
2791 peeeer2 460 2017-01-11 00:00:00.000 1 NULL 

Нежелательная запись здесь пользователь peeeer2 для кого, который я поставил InQueue = true , Мне нужно, чтобы удалить все эти дубликаты, где InQueue столбец устанавливается в 1 и другим критериям, в том, что имя пользователя является фактически дубликатом ...

Имя таблицы SearchedUsernames:

delete from SearchedUsernames 
where Username ?? 

Может кто-то помочь меня с этим?

Edit:

@TimSchmelter ти так много, это работает как шарм. Тем не менее, я получаю сообщение об ошибке. Мне нужно сначала сбросить соседние FK этой таблицы. Например, когда у меня есть соответствующая запись FK в соседнем столике под названием UserTransactions как следующее:

ID  SID        
---------------- 
162 162 
2791 2791  

мне нужно сначала удалить все записи в этой таблице соседней, а затем удалить дубликаты с помощью запроса, который вы написали. Тем не менее, на этот раз я бы хотел добавить ТОЛЬКО те, которые имеют дубликаты записей и установили InQueue = 0;

Так сценарий будет выглядеть следующим образом:

  1. уронить FK записывает SID из обоих дублей в соседних столов UserTransactions

  2. Затем выполнить запрос, DTV & Tim писал незначительные изменения в удаляйте только те записи, которые дублируются и установили InQueue = 0;

+3

Google много? Возможный дубликат [Как удалить повторяющиеся строки?] (Http://stackoverflow.com/questions/18932/how-can-i-remove-duplicate-rows) – HoneyBadger

+0

@HoneyBadger да Я понимаю ваше утверждение. Однако, поскольку у меня есть около 400 тыс. Записей в таблице, я не мог бы рискнуть написать запрос самостоятельно, если вы понимаете мою озабоченность ... – User987

+1

Не совсем, вы всегда можете сделать (меньшую) резервную копию таблицы для тестирования на. – HoneyBadger

ответ

5
WITH cte AS (
    SELECT Username, inqueue, 
     ROW_NUMBER() OVER (PARTITION BY Username ORDER BY InQueue ASC) AS RN 
    FROM searchedUsernames 
) 
DELETE FROM cte 
WHERE RN > 1; 

Если вы боитесь больше одного Inqueue = 0, а затем использовать RANK

WITH cte AS (
    SELECT Username, inqueue, 
     RANK() OVER (PARTITION BY Username ORDER BY InQueue ASC) AS RN 
    FROM searchedUsernames 
) 
DELETE FROM cte 
WHERE RN > 1; 
+1

@TimSchmelter Спасибо. Он исправлен. – DVT

+2

Я вижу одну проблему: если есть два 'InQueue = 0' и один' InQueue = 1' с тем же именем. Если я правильно понимаю ОП, то только 'InQueue = 1' следует удалить. Вы также удалите второй 'InQueue = 0'. Возможно, это невозможно, тогда нет проблем –

+0

@TimSchmelter да, это правильно, если запрос будет изменен? – User987

1

Вы можете использовать автообъединение так:

DELETE t0 
FROM SearchedUsernames t0 
INNER JOIN SearchedUsernames t1 ON(t0.Username = t1.Username AND t0.IsQueue <> T1.IsQueue) 
WHERE AND t0.IsQueue = 1 
3

Вероятно, наиболее интуитивным решением будет:

delete s from SearchedUsernames s 
where InQueue = 1 and exists(select * from SearchedUsernames 
          where InQueue = 0 and Username = s.Username) 
Смежные вопросы