Удаление повторяющейся записи из таблицы - SQL-запрос - PullRequest
6 голосов
/ 17 ноября 2009

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

Как я могу получить это? Пожалуйста, помогите мне.

Ответы [ 7 ]

12 голосов
/ 17 ноября 2009

Пожалуйста, попробуйте следующий запрос, он точно будет соответствовать вашей цели

SET ROWCOUNT 1
DELETE test
FROM test a
WHERE (SELECT COUNT(*) FROM test b WHERE b.name = a.name) > 1
WHILE @@rowcount > 0
  DELETE test
  FROM test a
  WHERE (SELECT COUNT(*) FROM test b WHERE b.name = a.name) > 1
SET ROWCOUNT 0

, где test - имя вашей таблицы

4 голосов
/ 17 ноября 2009

Это работает в SQL Server, хотя это не единственный оператор:

Declare @cnt int; 
Select @cnt=COUNT(*) From DupTable Where (Col1=1);  -- Assumes you are trying to delete the duplicates where some condition (e.g. Col1=1) is true.
Delete Top (@cnt-1) From DupTable

Также не требуется никаких дополнительных предположений (например, наличие другого столбца, который делает каждую строку уникальной). В конце концов, Сантану сказал, что строк являются дубликатами, а не только одним столбцом.

Однако правильный ответ , на мой взгляд, заключается в получении реальной структуры таблицы. То есть добавьте столбец IDENTITY в эту таблицу, чтобы вы могли использовать одну команду SQL для выполнения своей работы. Как это:

ALTER TABLE dbo.DupTable ADD
    IDCol int NOT NULL IDENTITY (1, 1)
GO

Тогда удаление тривиально:

DELETE FROM DupTable WHERE IDCol NOT IN 
   (SELECT MAX(IDCol) FROM DupTable GROUP BY Col1, Col2, Col3)
3 голосов
/ 17 ноября 2009
DELETE FROM Table t1, Table t2 WHERE t1.colDup = t2.colDup AND t1.date < t2.date

Удаляет все повторяющиеся строки из Table (в столбце colDup), за исключением самой старой (то есть lowset date).

2 голосов
/ 17 ноября 2009
DELETE FROM `mytbl`
    INNER JOIN (
        SELECT 1 FROM `mytbl`
        GROUP BY `duplicated_column` HAVING COUNT(*)=2
    ) USING(`id`)

Edit:

Мой плохой, приведенный выше запрос не будет работать.

Предполагая структуру таблицы:

id int auto_increment

num int # <- это столбец с дублированными значениями </p>

Следующий запрос будет работать в MySQL (я проверял):

DELETE `mytbl` FROM `mytbl` 
    INNER JOIN 
    (
        SELECT `num` FROM `mytbl`
        GROUP BY `num` HAVING COUNT(*)=2
    ) AS `tmp` USING (`num`)

Запрос удалит строки, имеющие 2 (не более или более) дублированных значения в столбце num.

Редактировать (снова):

Я предлагаю добавить ключ к столбцу num.

Edit (# 3):

В случае, если автор хотел удалить дублирующиеся строки , для MySQL должно работать следующее (у меня это работает):

DELETE `delete_duplicated_rows` FROM `delete_duplicated_rows`
    NATURAL JOIN (
        SELECT *
        FROM `delete_duplicated_rows`
        GROUP BY `num1` HAVING COUNT(*)=2
    ) AS `der`

Предполагая, что структура таблицы:

CREATE TABLE `delete_duplicated_rows` (
  `num1` tinyint(4) DEFAULT NOT NULL,
  `num2` tinyint(4) DEFAULT NOT NULL
) ENGINE=MyISAM;
1 голос
/ 29 сентября 2010
  -- Just to demonstrates Marks example          
    . 
        -- START === 1.0.dbo..DuplicatesTable.TableCreate.sql
    /****** Object:  Table [dbo].[DuplicatesTable] 
        Script Date: 03/29/2010 21:24:02 ******/
      IF EXISTS (SELECT * FROM sys.objects 
     WHERE 
object_id = OBJECT_ID(N'[dbo].[DuplicatesTable]') 
AND type in (N'U'))
        DROP TABLE [dbo].[DuplicatesTable]
    GO

    /****** Object:  Table [dbo].[DuplicatesTable]    
Script Date: 03/29/2010 21:24:02 ******/
    SET ANSI_NULLS ON
    GO

    SET QUOTED_IDENTIFIER ON
    GO

    CREATE TABLE [dbo].[DuplicatesTable](
        [ColA] [varchar](10) NOT NULL, -- the name of the DuplicatesTable
        [ColB] [varchar](10) NULL,  -- the description of the e DuplicatesTable 
     ) 


    /* 
    <doc> 
    Models a DuplicatesTable for 
    </doc>

    */


    GO


    --============================================================ DuplicatesTable START
    declare @ScriptFileName varchar(2000)
    SELECT @ScriptFileName = '$(ScriptFileName)'
    SELECT @ScriptFileName + ' --- DuplicatesTable START =========================================' 
    declare @TableName varchar(200)
    select @TableName = 'DuplicatesTable'

    SELECT 'SELECT name from sys.tables where name =''' + @TableName + ''''
    SELECT name from sys.tables 
    where name = @TableName

    DECLARE @TableCount INT 
    SELECT @TableCount  = COUNT(name ) from sys.tables 
        where name =@TableName

    if @TableCount=1
    SELECT ' DuplicatesTable PASSED. The Table ' + @TableName + ' EXISTS ' 
    ELSE 
    SELECT ' DuplicatesTable FAILED. The Table ' + @TableName + ' DOES NOT EXIST ' 
    SELECT @ScriptFileName + ' --- DuplicatesTable END =========================================' 
    --============================================================ DuplicatesTable END

    GO


    -- END ===  1.0.dbo..DuplicatesTable.TableCreate.sql

    . 
    -- START === 1.1..dbo..DuplicatesTable.TableInsert.sql

    BEGIN TRANSACTION;
    INSERT INTO [dbo].[DuplicatesTable]([ColA], [ColB])
    SELECT   N'ColA', N'ColB' UNION ALL
    SELECT N'ColA', N'ColB' UNION ALL
    SELECT  N'ColA', N'ColB' UNION ALL
    SELECT  N'ColA', N'ColB' UNION ALL
    SELECT  N'ColA', N'ColB' UNION ALL
    SELECT  N'ColA', N'ColB' UNION ALL
    SELECT  N'ColA', N'ColB' UNION ALL
    SELECT  N'ColA1', N'ColB1' UNION ALL
    SELECT  N'ColA1', N'ColB1' UNION ALL
    SELECT  N'ColA1', N'ColB1' UNION ALL
    SELECT  N'ColA1', N'ColB1' UNION ALL
    SELECT  N'ColA1', N'ColB1' UNION ALL
    SELECT  N'ColA1', N'ColB1' UNION ALL
    SELECT  N'ColA1', N'ColB1'
    COMMIT;
    RAISERROR (N'[dbo].[DuplicatesTable]: Insert Batch: 1.....Done!', 10, 1) WITH NOWAIT;
    GO


    -- END ===  1.1..dbo..DuplicatesTable.TableInsert.sql

    . 
    -- START === 2.0.RemoveDuplicates.Script.sql
    ALTER TABLE dbo.DuplicatesTable ADD
            DuplicatesTableId int NOT NULL IDENTITY (1, 1)
    GO

    -- Then the delete is trivial:
    DELETE FROM dbo.DuplicatesTable WHERE DuplicatesTableId NOT IN 
         (SELECT MAX(DuplicatesTableId) FROM dbo.DuplicatesTable GROUP BY ColA , ColB)

         Select * from DuplicatesTable ;  
    -- END ===  2.0.RemoveDuplicates.Script.sql
1 голос
/ 17 ноября 2009

Я думаю, что каждая таблица имеет уникальный идентификатор. Поэтому, если он существует, вы можете написать следующий запрос: Удалить Table1 из Table1 t1, где 2> = (выберите count (id) из Table1, где dupColumn = t1.dupColumn) и t1.id отсутствует (выберите max (id) из таблицы 1, где dupColumn = t1.dupColumn)

OOps. Кажется, можно использовать только второй фильтр Удалить Table1 из Table1 t1 где t1.id отсутствует (выберите max (id) из таблицы 1, где dupColumn = t1.dupColumn)

1 голос
/ 17 ноября 2009

Если у вас есть идентификаторы строк, которые вы хотите удалить, тогда ...

DELETE FROM table WHERE id IN (1, 4, 7, [id numbers to delete...])
...