删除主键重复的行 - SQL

时间:2016-10-04 05:06:21

标签: sql duplicates rows

我的问题是如何删除主键行以防它重复。其他字段可能/可能不是重复的。我只对重复的主键感兴趣,并希望在删除其他重复条目时保留第一个实例。

例如,

我有2个表格,其中包含以下数据:

表1: - 投资组合

列: - PortfolioID(PK),PortfolioName

示例数据: -

  1,北美洲   2,欧洲
   3,亚洲

表2: - 帐户

列: - AccountID(PK),PortfolioID(FK),AccountName

示例数据: -

  

1,1,地震

     

1,1,风

     

2,1,火

     

3,1,地震

     

4,2,洪水

     

5,2,风

假设对于PortfolioID = 1, 我试图从Account表中删除第2行,其中对于PortfolioID = 1,重复AccountID 1。我尝试使用CTE表达式,我使用ROW_NUMBER语句并尝试删除ROWNUMBER<> 1.但是这个查询不起作用,因为它删除了表中的所有行。

我试过的查询:

    WITH CTE AS
    (
    SELECT ROW_NUMBER() OVER (PARTITION BY [Account].[AccountID] ORDER BY [Account].[AccountID]) AS [ROWNUMBER],
    [Account].[AccountID]
    FROM [Account]
   INNER JOIN [Portfolio] ON [Portfolio].[PortfolioID] = [Account]. [PortfolioID]
   WHERE [Portfolio].[PortfolioID] = 1
   )

 DELETE [Account]
 FROM   [CTE] 
 WHERE  [ROWNUMBER] <> 1

我在查询中做错了什么?在此先感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

首先,如果您将AccountID列定义为数据库中的主键,这将有助于解决此类问题。

其次,您使用的是Sql Server吗?哪个版本?

假设您正在使用Sql Server和允许您使用窗口的最新版本,您可以尝试这样的操作来删除您拥有的任何重复项。

这将删除所有重复的副​​本:

WITH CTE AS
(SELECT *,R=RANK() OVER (ORDER BY AccountID,PortfolioID)
FROM Account)

DELETE CTE
WHERE R IN (SELECT R FROM CTE GROUP BY R HAVING COUNT(*)>1)

如果您愿意,可以使用此备用脚本保留其中一个副本:

WITH CTE AS
(
SELECT *,ROW_NUMBER() OVER (PARTITION BY AccountID,PortfolioID ORDER BY     AccountID,PortfolioID) AS RN
FROM Account
)

DELETE FROM CTE WHERE RN<>1

最后,如果您只想删除投资组合ID 1的重复项:

WITH CTE AS
(
SELECT *,ROW_NUMBER() OVER (PARTITION BY AccountID,PortfolioID ORDER BY     AccountID,PortfolioID) AS RN
FROM Account
Where PortfolioID = 1
)

DELETE FROM CTE WHERE RN<>1

答案 1 :(得分:0)

主键列永远不会支持重复的条目。

根据给定的数据/输入,尝试使用以下查询获得所需的结果。

;WITH CTE AS
    (
    SELECT ROW_NUMBER() OVER (PARTITION BY a.[AccountID],a.PortfolioID ORDER BY a.[AccountID]) AS [ROWNUMBER],*
    FROM [Account] a
   WHERE a.[PortfolioID] = 1
   )
   DELETE
   FROM   [CTE] 
   WHERE  [ROWNUMBER] > 1
相关问题