我的问题是如何删除主键行以防它重复。其他字段可能/可能不是重复的。我只对重复的主键感兴趣,并希望在删除其他重复条目时保留第一个实例。
例如,
我有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
我在查询中做错了什么?在此先感谢您的帮助。
答案 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