【问题标题】:Deleting rows where the Primary key is duplicated - SQL删除主键重复的行 - SQL
【发布时间】:2017-02-12 03:52:01
【问题描述】:

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

例如,

我有 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 行,其中 AccountID 1 重复 PortfolioID =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

我在查询中做错了吗?提前感谢您的帮助。

【问题讨论】:

  • 主键列怎么会有重复值?你确定你的问题吗?
  • AccountID 显然不是表的主键,否则根本不可能有重复项。但是,到目前为止,我无法在您的查询中发现任何错误。

标签: sql duplicates rows


【解决方案1】:

首先,如果您将 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

最后,如果您只想删除 Portfolio 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

【讨论】:

  • 我想我没有提到我在 Account 表上删除了 PK 约束。
  • 感谢您的回复,如果我们不加入表格,则此查询有效。但是假设我们要加入多个表,例如,投资组合链接到 PortfolioID 上的帐户,帐户链接到帐户 ID 上的策略,并且我的策略表中 PolicyID (PK) 字段中有重复项。我将如何编写删除语句我希望删除策略表中的重复行? DELETE [Policy] FROM CTE WHERE WHERE 1 对我不起作用。请指教,谢谢。
  • 老实说,如果您有多个表存在重复问题,我会一次处理一张表。如果要从策略表而不是帐户表中删除重复项,则必须更改 CTE 代码,而不仅仅是删除。
【解决方案2】:

主键列从不支持重复条目。

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

;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

【讨论】:

    猜你喜欢
    • 2017-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-11
    • 2010-11-02
    相关资源
    最近更新 更多