用于在存储过程中删除重复项的用户定义值

时间:2015-03-06 11:57:52

标签: sql sql-server stored-procedures

我目前正在使用以下代码:

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

我希望它根据传递给它的定义值循环并删除重复项(同时保留一行重复数据)。

目前,我的数据库表中没有显示任何更改。我理解这是由于我设置的@GUID值,但我不知道如何处理这个问题。

这不是前面提到的重复问题的重复问题,因为它重点关注&#39;关于删除用户WITH重复的约束。

4 个答案:

答案 0 :(得分:2)

试试这个:

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

答案 1 :(得分:1)

试试这个。不需要循环。

 DELETE FROM iwfAccountOpening WHERE Idx6 in (SELECT MIN(idx6) 
                 FROM iwfAccountOpening 
                 WHERE Idx29 = @ReferenceNumber 
                 GROUP BY Idx37 
                 HAVING COUNT(*) > 1) and Idx29 = @ReferenceNumber 

答案 2 :(得分:1)

您可以通过以下示例查询找到所有重复记录

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 )
   )

答案 3 :(得分:1)

这个周期:

WHILE (@GUID IS NOT NULL)
BEGIN
    DELETE FROM iwfAccountOpening WHERE Idx6 = @GUID;
END

看起来很奇怪。

首先,如果@GUID不为空 - 这将是无限循环,因为你是 不修改循环内的@GUID

第二 - 这个删除语句不会帮助你实现你的目标“删除除一个之外的所有重复” - 只是因为在这里你只删除一个你之前确定过的GUID的记录。

根据您的逻辑,它应该类似于

DELETE FROM iwfAccountOpening 
WHERE Idx29 = @ReferenceNumber and idx6 <> @GUID

不需要循环。

同样SELECT TOP 1 MIN(idx6)对我来说似乎有点多余。它可以只是SELECT MIN(idx6),你会得到相同的结果。