2010-07-27 2 views
7

Скажут у меня есть повторяющиеся строки в моей таблице и хорошо мой дизайн базы данных 3-го класса: -Как полностью удалить повторяющиеся строки

Insert Into tblProduct (ProductId,ProductName,Description,Category) Values (1,'Cinthol','cosmetic soap','soap'); 
Insert Into tblProduct (ProductId,ProductName,Description,Category) Values (1,'Cinthol','cosmetic soap','soap'); 
Insert Into tblProduct (ProductId,ProductName,Description,Category) Values (1,'Cinthol','cosmetic soap','soap'); 
Insert Into tblProduct (ProductId,ProductName,Description,Category) Values (1,'Lux','cosmetic soap','soap'); 
Insert Into tblProduct (ProductId,ProductName,Description,Category) Values (1,'Crowning Glory','cosmetic soap','soap'); 
Insert Into tblProduct (ProductId,ProductName,Description,Category) Values (2,'Cinthol','nice soap','soap'); 
Insert Into tblProduct (ProductId,ProductName,Description,Category) Values (3,'Lux','nice soap','soap'); 
Insert Into tblProduct (ProductId,ProductName,Description,Category) Values (3,'Lux','nice soap','soap'); 

Я хочу только один экземпляр каждой строки должен присутствовать в моей таблице. Таким образом, 2nd, 3rd and last row, которые полностью идентичны, должны быть удалены. Какой запрос я могу написать для этого? Можно ли это сделать без создания временных таблиц? Только в одном запросе?

Заранее спасибо :)

+0

Первая запись на основе порядка ввода? Для какой версии SQL Server? –

+0

Sql Server 2008. – TCM

+0

Я собираюсь предположить, что вы имеете в виду третью нормальную форму, когда говорите 3-й класс. Если это позволяет полные дубликаты в таблице, это не по 3NF по определению;) –

ответ

18

Попробуйте - это удалить все дубликаты из таблицы:

;WITH duplicates AS 
(
    SELECT 
     ProductID, ProductName, Description, Category, 
     ROW_NUMBER() OVER (PARTITION BY ProductID, ProductName 
          ORDER BY ProductID) 'RowNum' 
    FROM dbo.tblProduct 
) 
DELETE FROM duplicates 
WHERE RowNum > 1 
GO 

SELECT * FROM dbo.tblProduct 
GO 

Ваши дубликаты должны исчезнуть в настоящее время: выход:

ProductID ProductName DESCRIPTION  Category 
    1   Cinthol   cosmetic soap  soap 
    1   Lux    cosmetic soap  soap 
    1   Crowning Glory cosmetic soap  soap 
    2   Cinthol   nice soap   soap 
    3   Lux    nice soap   soap 
+2

+1: Drats - beaten –

+0

Nice Marc_s, это вопрос CTE? Если это так, не нужно ли в запросе CTE иметь предложение 'union'? – TCM

+0

@Nitesh Panchal: да, CTE являются одной из недоиспользуемых функций SQL Server - как и предложение OVER() :-) –

0

Первое использование SELECT... INTO:

SELECT DISTINCT ProductID, ProductName, Description, Category 
    INTO tblProductClean 
    FROM tblProduct 

Снижения, первая таблица.

+5

Из OP: «Можно ли это сделать без создания временных таблиц? Просто в одном запросе?» – dcp

4
DELETE tblProduct 
FROM tblProduct 
LEFT OUTER JOIN (
    SELECT MIN(ProductId) as ProductId, ProductName, Description, Category 
    FROM tblProduct 
    GROUP BY ProductName, Description, Category 
) as KeepRows ON 
    tblProduct.ProductId= KeepRows.ProductId 
WHERE 
    KeepRows.ProductId IS NULL 

Похищенные из How can I remove duplicate rows?

UPDATE:

Это будет работать только если ProductID является первичным ключом (который не является). Вам лучше использовать метод @marc_s, но я оставлю это на случай, если кто-то использует PK, попадет на этот пост.

+1

@Abe: 'rowid' был основным ключом для таблицы; Я думал, что это синтаксис Oracle на мгновение, пока я не увидел ссылку. –

+0

Я предполагал, что ProductId был основным ключом в его таблице. Я обновил его именами столбцов, чтобы избежать путаницы. –

+0

Nice Abe Miessler. Проголосовал – TCM

1

Я должен был сделать это несколько недель назад ... какую версию SQL Server вы используете? В SQL Server 2005 и выше, вы можете использовать row_number как часть вашего выбора, и только выбрать, где row_number равен 1. Я забыл точный синтаксис, но это хорошо документированы ... что-то вдоль линий:

Select t0.ProductID, 
     t0.ProductName, 
     t0.Description, 
     t0.Category 
Into tblCleanData 
From (
    Select ProductID, 
      ProductName, 
      Description, 
      Category, 
      Row_Number() Over (
       Partition By ProductID, 
          ProductName, 
          Description, 
          Category 
       Order By  ProductID, 
          ProductName, 
          Description, 
          Category 
      ) As RowNumber 
    From MyTable 
) As t0 
Where t0.RowNumber = 1 

Отъезд http://msdn.microsoft.com/en-us/library/ms186734.aspx, это должно заставить вас двигаться в правильном направлении.

+1

Правда, но OP нуждается в инструкции DELETE ... –

+0

@OMG Ponies - Er, хорошая точка. – BenAlabaster

+0

+1 Бен хотя .. – TCM

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