用于删除存储过程中重复项的用户定义值
User Defined Value for Deleting Duplicates in Stored Procedure
我目前正在使用以下代码:
ALTER PROCEDURE [dbo].[sp_TidyBasket]
@ReferenceNumber VARCHAR
AS
BEGIN
BEGIN TRANSACTION
DECLARE
@GUID VARCHAR,
@ErrorCode INT
--Get the First Reference Number of a basket item being duplicated
SET @GUID = (SELECT TOP 1 MIN(idx6)
FROM iwfAccountOpening
WHERE Idx29 = @ReferenceNumber
GROUP BY Idx37
HAVING COUNT(*) > 1)
--Executes a while loop whilst there is duplicates to be removed
WHILE (@GUID IS NOT NULL)
BEGIN
DELETE FROM iwfAccountOpening WHERE Idx6 = @GUID;
END
--Rollbacks transactions when any errors occur
SELECT @ErrorCode = @@ERROR
IF (@ErrorCode <> 0) GOTO PROBLEM
COMMIT TRANSACTION
PROBLEM:
IF (@ErrorCode <> 0) BEGIN
ROLLBACK TRANSACTION
END
END
我希望它根据传递给它的定义值循环并删除重复项(同时保留一行重复数据)。
目前我的数据库没有显示任何变化 table。我知道这是由于我设置的 @GUID
值造成的,但我不知道如何解决这个问题。
这不是前面提到的重复问题的重复问题,因为它侧重于删除用户设置的具有重复项的约束。
试试这个。无需循环。
DELETE FROM iwfAccountOpening WHERE Idx6 in (SELECT MIN(idx6)
FROM iwfAccountOpening
WHERE Idx29 = @ReferenceNumber
GROUP BY Idx37
HAVING COUNT(*) > 1) and Idx29 = @ReferenceNumber
您可以通过以下示例查询找到所有重复记录
SELECT YourColumn, COUNT(*) TotalCount
FROM YourTable
GROUP BY YourColumn
HAVING COUNT(*) > 1
ORDER BY COUNT(*) DESC
在你的情况下你也可以这样做
Delete from iwfAccountOpening Where Idx29 in
( SELECT Count(idx6)
FROM iwfAccountOpening
WHERE Idx29 = @ReferenceNumber
GROUP BY Idx6,Idx37
HAVING COUNT(*) > 1
ORDER BY COUNT(*) DESC )
)
本次循环:
WHILE (@GUID IS NOT NULL)
BEGIN
DELETE FROM iwfAccountOpening WHERE Idx6 = @GUID;
END
看起来很奇怪。
首先,如果 @GUID
不为空 - 这将是无限循环,因为你
不修改 @GUID
内部循环。
其次 - 此删除语句不会帮助您实现目标 "delete all duplicate except one" - 只是因为在这里您只删除了一条您之前确定的具有 GUID 的记录。
按照你的逻辑,应该是这样的
DELETE FROM iwfAccountOpening
WHERE Idx29 = @ReferenceNumber and idx6 <> @GUID
而且不需要周期。
另外 SELECT TOP 1 MIN(idx6)
对我来说看起来有点多余。它可以只是 SELECT MIN(idx6)
,你会得到相同的结果。
试试这个:
ALTER PROCEDURE [dbo].[sp_TidyBasket]
@ReferenceNumber VARCHAR
AS
BEGIN TRY
BEGIN TRANSACTION;
WITH cte
AS ( SELECT idx6 ,
ROW_NUMBER() OVER ( PARTITION BY Idx37 ORDER BY ( SELECT ( 1 ) ) ) AS RN
FROM iwfAccountOpening
WHERE Idx29 = @ReferenceNumber
)
DELETE i
FROM cte c
JOIN iwfAccountOpening i ON c.idx6 = i.idx6
WHERE Idx29 = @ReferenceNumber AND RN > 1
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION
END CATCH
GO
我目前正在使用以下代码:
ALTER PROCEDURE [dbo].[sp_TidyBasket]
@ReferenceNumber VARCHAR
AS
BEGIN
BEGIN TRANSACTION
DECLARE
@GUID VARCHAR,
@ErrorCode INT
--Get the First Reference Number of a basket item being duplicated
SET @GUID = (SELECT TOP 1 MIN(idx6)
FROM iwfAccountOpening
WHERE Idx29 = @ReferenceNumber
GROUP BY Idx37
HAVING COUNT(*) > 1)
--Executes a while loop whilst there is duplicates to be removed
WHILE (@GUID IS NOT NULL)
BEGIN
DELETE FROM iwfAccountOpening WHERE Idx6 = @GUID;
END
--Rollbacks transactions when any errors occur
SELECT @ErrorCode = @@ERROR
IF (@ErrorCode <> 0) GOTO PROBLEM
COMMIT TRANSACTION
PROBLEM:
IF (@ErrorCode <> 0) BEGIN
ROLLBACK TRANSACTION
END
END
我希望它根据传递给它的定义值循环并删除重复项(同时保留一行重复数据)。
目前我的数据库没有显示任何变化 table。我知道这是由于我设置的 @GUID
值造成的,但我不知道如何解决这个问题。
这不是前面提到的重复问题的重复问题,因为它侧重于删除用户设置的具有重复项的约束。
试试这个。无需循环。
DELETE FROM iwfAccountOpening WHERE Idx6 in (SELECT MIN(idx6)
FROM iwfAccountOpening
WHERE Idx29 = @ReferenceNumber
GROUP BY Idx37
HAVING COUNT(*) > 1) and Idx29 = @ReferenceNumber
您可以通过以下示例查询找到所有重复记录
SELECT YourColumn, COUNT(*) TotalCount
FROM YourTable
GROUP BY YourColumn
HAVING COUNT(*) > 1
ORDER BY COUNT(*) DESC
在你的情况下你也可以这样做
Delete from iwfAccountOpening Where Idx29 in
( SELECT Count(idx6)
FROM iwfAccountOpening
WHERE Idx29 = @ReferenceNumber
GROUP BY Idx6,Idx37
HAVING COUNT(*) > 1
ORDER BY COUNT(*) DESC )
)
本次循环:
WHILE (@GUID IS NOT NULL)
BEGIN
DELETE FROM iwfAccountOpening WHERE Idx6 = @GUID;
END
看起来很奇怪。
首先,如果 @GUID
不为空 - 这将是无限循环,因为你
不修改 @GUID
内部循环。
其次 - 此删除语句不会帮助您实现目标 "delete all duplicate except one" - 只是因为在这里您只删除了一条您之前确定的具有 GUID 的记录。
按照你的逻辑,应该是这样的
DELETE FROM iwfAccountOpening
WHERE Idx29 = @ReferenceNumber and idx6 <> @GUID
而且不需要周期。
另外 SELECT TOP 1 MIN(idx6)
对我来说看起来有点多余。它可以只是 SELECT MIN(idx6)
,你会得到相同的结果。
试试这个:
ALTER PROCEDURE [dbo].[sp_TidyBasket]
@ReferenceNumber VARCHAR
AS
BEGIN TRY
BEGIN TRANSACTION;
WITH cte
AS ( SELECT idx6 ,
ROW_NUMBER() OVER ( PARTITION BY Idx37 ORDER BY ( SELECT ( 1 ) ) ) AS RN
FROM iwfAccountOpening
WHERE Idx29 = @ReferenceNumber
)
DELETE i
FROM cte c
JOIN iwfAccountOpening i ON c.idx6 = i.idx6
WHERE Idx29 = @ReferenceNumber AND RN > 1
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION
END CATCH
GO