【问题标题】:deleting duplicate rows?删除重复行?
【发布时间】:2013-11-07 05:27:28
【问题描述】:

我想根据类别 ID 从我的表中删除重复的行,但不想全部删除,如果有多个具有相同类别 ID 的行,我想留下一行。

这是我的查询,我需要更改它。

delete from twinhead_tblcategory  where categoryid in (select categoryid from twinhead_tblcategory group by categoryid having count(categoryid) > 1 )

【问题讨论】:

标签: sql


【解决方案1】:

对于 SQL Server,您可以这样做:

WITH MyTableCTE (CategoryId, RowNumber)
AS
(
    SELECT CategoryId, ROW_NUMBER() OVER (ORDER BY CategoryId) AS 'RowNumber'
    FROM MyTable

)

Delete From MyTableCTE Where RowNumber > 1

【讨论】:

【解决方案2】:

在新表中做一个select distinct,删除旧表并将新表重命名为旧表名。

【讨论】:

    【解决方案3】:

    如果您的行有一个不同的 id 列,那么这应该可以:

    DELETE t1 FROM your_table t1, your_table t2 
    WHERE t1.column1 = t2.column1 AND t1.column2 = t2.column2
    AND ... /* check equality of all relevant columns */
    AND t1.id < t2.id
    

    【讨论】:

      【解决方案4】:

      在此处查看 sql server - http://support.microsoft.com/kb/139444 - 这应该可以帮助您入门。

      【讨论】:

        【解决方案5】:

        这可能是笨拙的,但也许您可以在临时表中选择 distinct *,然后截断该表,然后将临时表的内容插入表中。不过,外键约束可能会阻止这种情况。

        【讨论】:

          【解决方案6】:

          对于 SqlServer,您可以使用游标遍历所有项目,按该 categoryID 排序。

          当前的ID和之前的ID一样吗?然后删除它,参见this article 的示例 C。 否则请记住下一轮的 ID。

          【讨论】:

            【解决方案7】:

            你有几种删除duplicate rows的方法。

            对于我的解决方案,首先以这张表为例

            CREATE TABLE #Employee
            (
            ID          INT,
            FIRST_NAME  NVARCHAR(100),
            LAST_NAME   NVARCHAR(300)
            )
            
            INSERT INTO #Employee VALUES ( 1, 'Vahid', 'Nasiri' );
            INSERT INTO #Employee VALUES ( 2, 'name1', 'lname1' );
            INSERT INTO #Employee VALUES ( 3, 'name2', 'lname2' );
            INSERT INTO #Employee VALUES ( 2, 'name1', 'lname1' );
            INSERT INTO #Employee VALUES ( 3, 'name2', 'lname2' );
            INSERT INTO #Employee VALUES ( 4, 'name3', 'lname3' );
            

            第一个解决方案:为重复行使用另一个表。

            SELECT DISTINCT *
            FROM   #Employee 
            
            SELECT * INTO #DuplicateEmployee
            FROM   #Employee
            
            INSERT #DuplicateEmployee
            SELECT DISTINCT *
            FROM   #Employee
            
            BEGIN TRAN 
            DELETE #Employee
            INSERT #Employee
            SELECT *
            FROM   #DuplicateEmployee
            
            COMMIT TRAN 
            
            DROP TABLE #DuplicateEmployee 
            
            SELECT DISTINCT *
            FROM   #Employee 
            

            第二种解决方案:

            SELECT DISTINCT * FROM #Employee
            
            SELECT * INTO #DuplicateEmployee FROM #Employee
            
            INSERT #DuplicateEmployee
            SELECT ID,
                FIRST_NAME,
                LAST_NAME
            FROM   #Employee
            GROUP BY
                ID,FIRST_NAME,LAST_NAME
            HAVING COUNT(*) > 1
            
            BEGIN TRAN
            DELETE #Employee
            FROM   #DuplicateEmployee
            WHERE  #Employee.ID = #DuplicateEmployee.ID
            AND #Employee.FIRST_NAME = #DuplicateEmployee.FIRST_NAME
            AND #Employee.LAST_NAME = #DuplicateEmployee.LAST_NAME
            
            INSERT #Employee
            SELECT *
            FROM   #DuplicateEmployee
            
            COMMIT TRAN
            DROP TABLE #DuplicateEmployee
            
            SELECT DISTINCT * FROM   #Employee
            

            撕裂的解决方案:使用rowcount

            SELECT DISTINCT *
            FROM   #Employee
            
            SET ROWCOUNT 1
            SELECT 1
            WHILE @@rowcount > 0
               DELETE #Employee
               WHERE  1 < (
                      SELECT COUNT(*)
                      FROM   #Employee a2
                      WHERE  #Employee.ID = a2.ID
                             AND #Employee.FIRST_NAME = a2.FIRST_NAME
                             AND #Employee.LAST_NAME = a2.LAST_NAME
                  )
            
            SET ROWCOUNT 0
            
            SELECT DISTINCT *
            FROM   #Employee
            

            第四个解决方案:使用Analytical Functions

            SELECT DISTINCT *
            FROM   #Employee;
            
            WITH #DeleteEmployee AS (
                                 SELECT ROW_NUMBER()
                                        OVER(PARTITION BY ID, First_Name, Last_Name ORDER BY ID) AS
                                        RNUM
                                 FROM   #Employee
                             )
            
            DELETE
            FROM   #DeleteEmployee
            WHERE  RNUM > 1
            
            SELECT DISTINCT *
            FROM   #Employee
            

            第五个解决方案:使用identity字段

            SELECT DISTINCT *
            FROM   #Employee;
            
            ALTER TABLE #Employee ADD UNIQ_ID INT IDENTITY(1, 1)
            
            DELETE
            FROM   #Employee
            WHERE  UNIQ_ID < (
                SELECT MAX(UNIQ_ID)
                FROM   #Employee a2
                WHERE  #Employee.ID = a2.ID
                       AND #Employee.FIRST_NAME = a2.FIRST_NAME
                       AND #Employee.LAST_NAME = a2.LAST_NAME
            )
            
            ALTER TABLE #Employee DROP COLUMN UNIQ_ID
            
            SELECT DISTINCT *
            FROM   #Employee
            

            所有解决方案的结尾都使用此命令

            DROP TABLE #Employee
            

            我的答案来源是this site

            【讨论】:

            • 您好,请不要在网站上发布重复的答案,因为这会产生噪音。相反,如果您发现重复的帖子,请将它们标记为重复。您只需要 15 声望即可标记帖子。详情请见duplicate answers
            • 您好@loup,您的回答已被系统自动标记并被版主删除。该系统旨在寻找可疑或有问题的活动,并引起社区的注意。如果您编辑您的帖子以修复链接以将其从“此站点”更改为实际说出该站点的名称以便有适当的归属,我可以删除该反对票。祝你好运!
            • 如果您发现重复问题,请使用问题下方的“标记”链接将其标记为另一个问题的重复问题。请参阅flag posts privilege 页面了解更多详情。祝你好运!
            猜你喜欢
            • 2018-04-07
            • 2012-05-31
            • 1970-01-01
            • 2017-09-29
            • 2010-10-07
            • 2012-12-07
            • 2020-04-22
            相关资源
            最近更新 更多