删除重复的行?

时间:2011-02-24 14:21:53

标签: sql

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

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

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

7 个答案:

答案 0 :(得分:4)

在新表中执行select distinct,删除旧表并将新表重命名为旧表名。

答案 1 :(得分:4)

对于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 :(得分: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

答案 3 :(得分:1)

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

答案 4 :(得分:1)

这可能很苛刻,但也许您可以选择不同的*进入临时表,然后截断表,然后将临时表的内容插入表中。但是,外键约束可能会阻止这种情况。

答案 5 :(得分:1)

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

当前ID是否与前一个ID相同?然后删除它,参见this article的示例C. 否则请记住下一轮的ID。

答案 6 :(得分:0)

您有几种方法可以删除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